summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/drivers/snes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/drivers/snes.c')
-rw-r--r--src/mess/drivers/snes.c771
1 files changed, 75 insertions, 696 deletions
diff --git a/src/mess/drivers/snes.c b/src/mess/drivers/snes.c
index 94573efb94c..24f9ab055f5 100644
--- a/src/mess/drivers/snes.c
+++ b/src/mess/drivers/snes.c
@@ -21,8 +21,7 @@
- Fix vertical mosaic effects
- Add support for real CX4 and ST018 CPUs
- Add support for SA-1 and SuperGB add-ons
- - Fix mouse & superscope support
- - Add multitap support
+ - Fix superscope support
- Add support for other controllers
***************************************************************************/
@@ -33,38 +32,17 @@
#include "includes/snes.h"
#include "machine/snescx4.h"
-#include "crsshair.h"
-
#include "bus/snes/snes_slot.h"
#include "bus/snes/snes_carts.h"
-
-struct snes_mouse
-{
- INT16 x, y, oldx, oldy;
- UINT16 buttons;
- UINT8 deltax, deltay;
- int speed;
-};
-
-struct snes_superscope
-{
- INT16 x, y;
- UINT8 buttons;
- int turbo_lock, pause_lock, fire_lock;
- int offscreen;
-};
-
+#include "bus/snes_ctrl/ctrl.h"
class snes_console_state : public snes_state
{
public:
- enum
- {
- TIMER_LIGHTGUN_TICK = TIMER_SNES_LAST
- };
-
snes_console_state(const machine_config &mconfig, device_type type, const char *tag)
: snes_state(mconfig, type, tag)
+ , m_ctrl1(*this, "ctrl1")
+ , m_ctrl2(*this, "ctrl2")
, m_cartslot(*this, "snsslot")
{ }
@@ -110,35 +88,20 @@ public:
TIMER_CALLBACK_MEMBER( lightgun_tick );
// input related
+ SNESCTRL_ONSCREEN_CB(onscreen_cb);
+ SNESCTRL_GUNLATCH_CB(gun_latch_cb);
virtual DECLARE_WRITE8_MEMBER(io_read);
virtual UINT8 oldjoy1_read(int latched);
virtual UINT8 oldjoy2_read(int latched);
-
- // pad inputs
- void input_read_joy(int port, bool multitap);
- UINT8 input_serial_pad(int port, int latched, bool multitap);
-
- // mouse inputs
- void input_read_mouse(int port);
- UINT8 input_serial_mouse(int port, int latched);
-
- // superscope inputs
- DECLARE_CUSTOM_INPUT_MEMBER( sscope_offscreen_input );
- void input_read_sscope(int port);
- UINT8 input_serial_sscope(int port, int latched);
- void gun_latch(INT16 x, INT16 y);
+ virtual void write_joy_latch(UINT8 data);
+ virtual void wrio_write(UINT8 data);
virtual void machine_start();
virtual void machine_reset();
int m_type;
+ required_device<snes_control_port_device> m_ctrl1;
+ required_device<snes_control_port_device> m_ctrl2;
optional_device<sns_cart_slot_device> m_cartslot;
-
-protected:
-
- snes_mouse m_mouse[2];
- snes_superscope m_scope[2];
-
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
};
@@ -1060,230 +1023,8 @@ ADDRESS_MAP_END
*
*************************************/
-void snes_console_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TIMER_LIGHTGUN_TICK:
- lightgun_tick(ptr, param);
- break;
- default:
- snes_state::device_timer(timer, id, param, ptr);
- break;
- }
-}
-
-TIMER_CALLBACK_MEMBER( snes_console_state::lightgun_tick )
-{
- if ((ioport("CTRLSEL")->read() & 0x0f) == 0x03 || (ioport("CTRLSEL")->read() & 0x0f) == 0x04) {
- /* enable lightpen crosshair */
- crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL);
- }
- else
- {
- /* disable lightpen crosshair */
- crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE);
- }
-
- if ((ioport("CTRLSEL")->read() & 0xf0) == 0x30 || (ioport("CTRLSEL")->read() & 0xf0) == 0x40)
- {
- /* enable lightpen crosshair */
- crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL);
- }
- else
- {
- /* disable lightpen crosshair */
- crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_NONE);
- }
-}
-
-static INPUT_PORTS_START( snes_joypads )
-
- PORT_START("JOY1")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Button B") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P1 Button Y") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P1 Select") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("P1 Start") PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Button A") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P1 Button X") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P1 Button L") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Button R") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
- PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
-
- PORT_START("JOY2")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Button B") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P2 Button Y") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P2 Select") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START2 ) PORT_NAME("P2 Start") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Button A") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P2 Button X") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P2 Button L") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Button R") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
- PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10)
-// temp hack to share the same port both for P2 alone and P2 through MP5 adapter
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Button B") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P2 Button Y") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P2 Select") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START2 ) PORT_NAME("P2 Start") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Button A") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P2 Button X") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P2 Button L") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Button R") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
-
- PORT_START("JOY3")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3 Button B") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P3 Button Y") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P3 Select") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START3 ) PORT_NAME("P3 Start") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3 Button A") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P3 Button X") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P3 Button L") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P3 Button R") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
-
- PORT_START("JOY4")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4 Button B") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P4 Button Y") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P4 Select") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START4 ) PORT_NAME("P4 Start") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4 Button A") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P4 Button X") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P4 Button L") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P4 Button R") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
-
- PORT_START("JOY5")
- PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P5 Button B") PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P5 Button Y") PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P5 Select") PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START5 ) PORT_NAME("P5 Start") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P5 Button A") PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P5 Button X") PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P5 Button L") PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P5 Button R") PORT_PLAYER(5) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
- PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x50)
-
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( snes_mouse )
- PORT_START("MOUSE1")
- /* bits 0,3 = mouse signature (must be 1) */
- PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_UNUSED )
- /* bits 4,5 = mouse speed: 0 = slow, 1 = normal, 2 = fast, 3 = unused */
- PORT_BIT( 0x0030, IP_ACTIVE_HIGH, IPT_UNUSED )
- /* bits 6,7 = mouse buttons */
- PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Mouse Button Left") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x02)
- PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Mouse Button Right") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x02)
- PORT_BIT( 0xff00, IP_ACTIVE_HIGH, IPT_SPECIAL ) // these must be 0!
-
- PORT_START("MOUSE1_X")
- PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x02)
-
- PORT_START("MOUSE1_Y")
- PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x02)
-
- PORT_START("MOUSE2")
- /* bits 0,3 = mouse signature (must be 1) */
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
- /* bits 4,5 = mouse speed: 0 = slow, 1 = normal, 2 = fast, 3 = unused */
- PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_UNUSED )
- /* bits 6,7 = mouse buttons */
- PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Mouse Button Left") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x20)
- PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Mouse Button Right") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x20)
-
- PORT_START("MOUSE2_X")
- PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x20)
-
- PORT_START("MOUSE2_Y")
- PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x20)
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( snes_superscope )
- PORT_START("SUPERSCOPE1")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // Noise
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, snes_console_state, sscope_offscreen_input, (void *)0)
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Port1 Superscope Pause") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x03)
- PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Port1 Superscope Turbo") PORT_TOGGLE PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x03)
- PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Port1 Superscope Cursor") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x03)
- PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Port1 Superscope Fire") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x03)
-
- PORT_START("SUPERSCOPE1_X")
- PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_NAME("Port1 Superscope X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x03)
-
- PORT_START("SUPERSCOPE1_Y")
- PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_NAME("Port1 Superscope Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x03)
-
- PORT_START("SUPERSCOPE2")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // Noise
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, snes_console_state, sscope_offscreen_input, (void *)1)
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Port2 Superscope Pause") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x30)
- PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Port2 Superscope Turbo") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x30)
- PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Port2 Superscope Cursor") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x30)
- PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Port2 Superscope Fire") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x30)
-
- PORT_START("SUPERSCOPE2_X")
- PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_NAME("Port2 Superscope X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x30)
-
- PORT_START("SUPERSCOPE2_Y")
- PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_NAME("Port2 Superscope Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x30)
-INPUT_PORTS_END
-
static INPUT_PORTS_START( snes )
- PORT_START("CTRLSEL") /* Select Controller Type */
- PORT_CONFNAME( 0x0f, 0x01, "P1 Controller")
- PORT_CONFSETTING( 0x00, "Unconnected" )
- PORT_CONFSETTING( 0x01, "Gamepad" )
- PORT_CONFSETTING( 0x02, "Mouse" )
- PORT_CONFSETTING( 0x03, "Superscope" )
-// PORT_CONFSETTING( 0x04, "Justfier" )
-// PORT_CONFSETTING( 0x05, "Multitap" )
- PORT_CONFNAME( 0xf0, 0x10, "P2 Controller")
- PORT_CONFSETTING( 0x00, "Unconnected" )
- PORT_CONFSETTING( 0x10, "Gamepad" )
- PORT_CONFSETTING( 0x20, "Mouse" )
- PORT_CONFSETTING( 0x30, "Superscope" )
-// PORT_CONFSETTING( 0x40, "Justfier" )
- PORT_CONFSETTING( 0x50, "Multitap" )
-
- PORT_INCLUDE(snes_joypads)
- PORT_INCLUDE(snes_mouse)
- PORT_INCLUDE(snes_superscope)
-
+ // input devices go through slot options
PORT_START("OPTIONS")
PORT_CONFNAME( 0x01, 0x00, "Hi-Res pixels blurring (TV effect)")
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
@@ -1349,446 +1090,97 @@ INPUT_PORTS_END
*
*************************************/
-// Mouse handling
-
-void snes_console_state::input_read_mouse(int port)
+WRITE8_MEMBER(snes_console_state::io_read)
{
- INT16 var;
- static const char *const portnames[2][3] =
- {
- { "MOUSE1", "MOUSE1_X", "MOUSE1_Y" },
- { "MOUSE2", "MOUSE2_X", "MOUSE2_Y" },
- };
-
- m_mouse[port].buttons = ioport(portnames[port][0])->read();
- m_mouse[port].x = ioport(portnames[port][1])->read();
- m_mouse[port].y = ioport(portnames[port][2])->read();
-
- var = m_mouse[port].x - m_mouse[port].oldx;
-
- if (var < -127)
- {
- m_mouse[port].deltax = 0xff;
- m_mouse[port].oldx -= 127;
- }
- else if (var < 0)
- {
- m_mouse[port].deltax = 0x80 | (-var);
- m_mouse[port].oldx = m_mouse[port].x;
- }
- else if (var > 127)
- {
- m_mouse[port].deltax = 0x7f;
- m_mouse[port].oldx += 127;
- }
- else
- {
- m_mouse[port].deltax = var & 0xff;
- m_mouse[port].oldx = m_mouse[port].x;
- }
-
- var = m_mouse[port].y - m_mouse[port].oldy;
-
- if (var < -127)
- {
- m_mouse[port].deltay = 0xff;
- m_mouse[port].oldy -= 127;
- }
- else if (var < 0)
- {
- m_mouse[port].deltay = 0x80 | (-var);
- m_mouse[port].oldy = m_mouse[port].y;
- }
- else if (var > 127)
- {
- m_mouse[port].deltay = 0x7f;
- m_mouse[port].oldy += 127;
- }
- else
+ // is automatic reading on? if so, read 16bits from oldjoy1/2
+ if (SNES_CPU_REG(NMITIMEN) & 1)
{
- m_mouse[port].deltay = var & 0xff;
- m_mouse[port].oldy = m_mouse[port].y;
- }
+ UINT16 joy1 = 0, joy2 = 0, joy3 = 0, joy4 = 0;
+ m_ctrl1->port_poll();
+ m_ctrl2->port_poll();
+
+ for (int i = 0; i < 16; i++)
+ {
+ joy1 |= ((m_ctrl1->read_pin4() & 1) << (15 - i));
+ joy2 |= ((m_ctrl2->read_pin4() & 1) << (15 - i));
+ joy3 |= ((m_ctrl1->read_pin5() & 1) << (15 - i));
+ joy4 |= ((m_ctrl2->read_pin5() & 1) << (15 - i));
+ }
- m_data1[port] = m_mouse[port].buttons;
- m_data2[port] = 0;
+ SNES_CPU_REG(JOY1L) = (joy1 & 0x00ff) >> 0;
+ SNES_CPU_REG(JOY1H) = (joy1 & 0xff00) >> 8;
+ SNES_CPU_REG(JOY2L) = (joy2 & 0x00ff) >> 0;
+ SNES_CPU_REG(JOY2H) = (joy2 & 0xff00) >> 8;
+ SNES_CPU_REG(JOY3L) = (joy3 & 0x00ff) >> 0;
+ SNES_CPU_REG(JOY3H) = (joy3 & 0xff00) >> 8;
+ SNES_CPU_REG(JOY4L) = (joy4 & 0x00ff) >> 0;
+ SNES_CPU_REG(JOY4H) = (joy4 & 0xff00) >> 8;
+ }
}
-UINT8 snes_console_state::input_serial_mouse(int port, int latched)
+UINT8 snes_console_state::oldjoy1_read(int latched)
{
- UINT8 res = 0;
-
- if (latched)
- {
- m_mouse[port].speed = (m_mouse[port].speed + 1) % 3;
- return res;
- }
-
- if (m_read_idx[port] >= 32)
- res |= 0x01;
- else if (m_read_idx[port] >= 24)
- res |= (m_mouse[port].deltax >> (31 - m_read_idx[port]++)) & 0x01;
- else if (m_read_idx[port] >= 16)
- res |= (m_mouse[port].deltay >> (23 - m_read_idx[port]++)) & 0x01;
- else if (m_read_idx[port] == 11)
- {
- res |= (m_mouse[port].speed >> 0) & 0x01;
- m_read_idx[port]++;
- }
- else if (m_read_idx[port] == 10)
- {
- res |= (m_mouse[port].speed >> 1) & 0x01;
- m_read_idx[port]++;
- }
- else
- res |= (m_mouse[port].buttons >> (15 - m_read_idx[port]++)) & 0x01;
+ UINT8 ret = 0;
+ ret |= m_ctrl1->read_pin4();
+ ret |= (m_ctrl1->read_pin5() << 1);
+ return ret;
+}
- return res;
+UINT8 snes_console_state::oldjoy2_read(int latched)
+{
+ UINT8 ret = 0;
+ ret |= m_ctrl2->read_pin4();
+ ret |= (m_ctrl2->read_pin5() << 1);
+ return ret;
}
-// Superscope handling
+void snes_console_state::write_joy_latch(UINT8 data)
+{
+ m_ctrl1->write_strobe(data);
+ m_ctrl2->write_strobe(data);
+}
-CUSTOM_INPUT_MEMBER( snes_console_state::sscope_offscreen_input )
+void snes_console_state::wrio_write(UINT8 data)
{
- int port = (FPTR)param;
- static const char *const portnames[2][3] =
+ if (!(SNES_CPU_REG(WRIO) & 0x80) && (data & 0x80))
{
- { "SUPERSCOPE1", "SUPERSCOPE1_X", "SUPERSCOPE1_Y" },
- { "SUPERSCOPE2", "SUPERSCOPE2_X", "SUPERSCOPE2_Y" },
- };
-
- INT16 x = ioport(portnames[port][1])->read();
- INT16 y = ioport(portnames[port][2])->read();
+ // external latch
+ m_ppu->set_latch_hv(m_ppu->current_x(), m_ppu->current_y());
+ }
- /* these are the theoretical boundaries, but we currently are always onscreen... */
- if (x < 0 || x >= SNES_SCR_WIDTH || y < 0 || y >= m_ppu->m_beam.last_visible_line)
- m_scope[port].offscreen = 1;
- else
- m_scope[port].offscreen = 0;
+ m_ctrl1->write_pin6(BIT(data, 6));
+ m_ctrl2->write_pin6(BIT(data, 7));
- return m_scope[port].offscreen;
}
-
-void snes_console_state::gun_latch(INT16 x, INT16 y)
+SNESCTRL_GUNLATCH_CB(snes_console_state::gun_latch_cb)
{
- /* these are the theoretical boundaries */
+ // these are the theoretical boundaries
if (x < 0)
x = 0;
if (x > (SNES_SCR_WIDTH - 1))
x = SNES_SCR_WIDTH - 1;
-
+
if (y < 0)
y = 0;
if (y > (m_ppu->m_beam.last_visible_line - 1))
y = m_ppu->m_beam.last_visible_line - 1;
- m_ppu->m_beam.latch_horz = x;
- m_ppu->m_beam.latch_vert = y;
- m_ppu->m_stat78 |= 0x40;
-}
-
-void snes_console_state::input_read_sscope(int port)
-{
- static const char *const portnames[2][3] =
- {
- { "SUPERSCOPE1", "SUPERSCOPE1_X", "SUPERSCOPE1_Y" },
- { "SUPERSCOPE2", "SUPERSCOPE2_X", "SUPERSCOPE2_Y" },
- };
- UINT8 input;
-
- /* first read input bits */
- m_scope[port].x = ioport(portnames[port][1])->read();
- m_scope[port].y = ioport(portnames[port][2])->read();
- input = ioport(portnames[port][0])->read();
-
- /* then start elaborating input bits: only keep old turbo value */
- m_scope[port].buttons &= 0x20;
-
- /* set onscreen/offscreen */
- m_scope[port].buttons |= BIT(input, 1);
-
- /* turbo is a switch; toggle is edge sensitive */
- if (BIT(input, 5) && !m_scope[port].turbo_lock)
- {
- m_scope[port].buttons ^= 0x20;
- m_scope[port].turbo_lock = 1;
- }
- else if (!BIT(input, 5))
- m_scope[port].turbo_lock = 0;
-
- /* fire is a button; if turbo is active, trigger is level sensitive; otherwise it is edge sensitive */
- if (BIT(input, 7) && (BIT(m_scope[port].buttons, 5) || !m_scope[port].fire_lock))
- {
- m_scope[port].buttons |= 0x80;
- m_scope[port].fire_lock = 1;
- }
- else if (!BIT(input, 7))
- m_scope[port].fire_lock = 0;
-
- /* cursor is a button; it is always level sensitive */
- m_scope[port].buttons |= BIT(input, 6);
-
- /* pause is a button; it is always edge sensitive */
- if (BIT(input, 4) && !m_scope[port].pause_lock)
- {
- m_scope[port].buttons |= 0x10;
- m_scope[port].pause_lock = 1;
- }
- else if (!BIT(input, 4))
- m_scope[port].pause_lock = 0;
-
- /* If we have pressed fire or cursor and we are on-screen and SuperScope is in Port2, then latch video signal.
- Notice that we only latch Port2 because its IOBit pin is connected to bit7 of the IO Port, while Port1 has
- IOBit pin connected to bit6 of the IO Port, and the latter is not detected by the H/V Counters. In other
- words, you can connect SuperScope to Port1, but there is no way SNES could detect its on-screen position */
- if ((m_scope[port].buttons & 0xc0) && !(m_scope[port].buttons & 0x02) && port == 1)
- gun_latch(m_scope[port].x, m_scope[port].y);
-
- m_data1[port] = 0xff | (m_scope[port].buttons << 8);
- m_data2[port] = 0;
-}
-
-UINT8 snes_console_state::input_serial_sscope(int port, int latched)
-{
- UINT8 res = 0;
-
- if (m_read_idx[port] >= 8)
- res |= 0x01;
- else
- res |= (m_scope[port].buttons >> (7 - m_read_idx[port]++)) & 0x01;
-
- return res;
-}
-
-// Joypad + Multitap handling
-// input_read_joy is used both for standard joys and for the MP5 multitap
-
-void snes_console_state::input_read_joy( int port, bool multitap )
-{
- static const char *const portnames[4][2] =
- {
- { "JOY1", "JOY3" },
- { "JOY2", "JOY3" },
- { "JOY4", "JOY5" },
- { "JOY4", "JOY5" }
- };
-
- if (!multitap)
- {
- m_data1[port] = ioport(portnames[port][0])->read();
- m_data2[port] = 0;
- // avoid sending signals that could crash games
- // if left, no right
- if (m_data1[port] & 0x200)
- m_data1[port] &= ~0x100;
- // if up, no down
- if (m_data1[port] & 0x800)
- m_data1[port] &= ~0x400;
- // if left, no right
- if (m_data2[port] & 0x200)
- m_data2[port] &= ~0x100;
- // if up, no down
- if (m_data2[port] & 0x800)
- m_data2[port] &= ~0x400;
- }
- else
- {
- m_data1[port] = ioport(portnames[port][0])->read();
- m_data2[port] = ioport(portnames[port][1])->read();
- m_data1[port + 2] = ioport(portnames[port + 2][0])->read();
- m_data2[port + 2] = ioport(portnames[port + 2][1])->read();
- // avoid sending signals that could crash games
- // if left, no right
- if (m_data1[port] & 0x200)
- m_data1[port] &= ~0x100;
- // if up, no down
- if (m_data1[port] & 0x800)
- m_data1[port] &= ~0x400;
- // if left, no right
- if (m_data2[port] & 0x200)
- m_data2[port] &= ~0x100;
- // if up, no down
- if (m_data2[port] & 0x800)
- m_data2[port] &= ~0x400;
- // if left, no right
- if (m_data1[port + 2] & 0x200)
- m_data1[port + 2] &= ~0x100;
- // if up, no down
- if (m_data1[port + 2] & 0x800)
- m_data1[port + 2] &= ~0x400;
- // if left, no right
- if (m_data2[port + 2] & 0x200)
- m_data2[port + 2] &= ~0x100;
- // if up, no down
- if (m_data2[port + 2] & 0x800)
- m_data2[port + 2] &= ~0x400;
- }
+// m_ppu->set_latch_hv(x, y); // it would be more accurate to write twice to WRIO register, first with bit7 = 0 and then with bit7 = 1
+ m_ppu->set_latch_hv(m_ppu->current_x(), m_ppu->current_y());
}
-UINT8 snes_console_state::input_serial_pad(int port, int latched, bool multitap)
+SNESCTRL_ONSCREEN_CB(snes_console_state::onscreen_cb)
{
- UINT8 res = 0;
-
- // multitap signature? Super Bomberman 3-5 do not like this at all...
- if (multitap)
- res |= 2;
- if (latched)
- return res;
-
- if (!multitap)
- {
- if (m_read_idx[port] >= 16)
- res |= 0x01;
- else
- {
- res |= (BIT(m_data1[port], (15 - m_read_idx[port])));
- res |= (BIT(m_data2[port], (15 - m_read_idx[port])) << 1);
- m_read_idx[port]++;
- }
- }
+ // these are the theoretical boundaries, but we currently are always onscreen due to the
+ // way IPT_LIGHTGUNs work... investigate more on this!
+ if (x < 0 || x >= SNES_SCR_WIDTH || y < 0 || y >= m_ppu->m_beam.last_visible_line)
+ return false;
else
- {
- int shift = !(SNES_CPU_REG(WRIO) & 0x80) ? 2 : 0;
- if (m_read_idx[port + shift] >= 16)
- res |= 0x03;
- else
- {
- res |= (BIT(m_data1[port + shift], (15 - m_read_idx[port + shift])));
- res |= (BIT(m_data2[port + shift], (15 - m_read_idx[port + shift])) << 1);
- m_read_idx[port + shift]++;
- }
- }
- return res;
+ return true;
}
-// input handling from the system side
-
-WRITE8_MEMBER(snes_console_state::io_read)
-{
- UINT8 ctrl1 = ioport("CTRLSEL")->read() & 0x0f;
- UINT8 ctrl2 = (ioport("CTRLSEL")->read() & 0xf0) >> 4;
- bool multitap0 = FALSE;
- bool multitap1 = FALSE;
-
- // Check if lightgun has been chosen as input: if so, enable crosshair
- timer_set(attotime::zero, TIMER_LIGHTGUN_TICK);
-
- switch (ctrl1)
- {
- case 1: // SNES joypad
- input_read_joy(0, FALSE);
- break;
- case 2: // SNES Mouse
- input_read_mouse(0);
- break;
- case 3: // SNES Superscope
- input_read_sscope(0);
- break;
- case 5: // SNES joypad(s) through MP5 multitap
- input_read_joy(0, TRUE);
- multitap0 = TRUE;
- break;
- case 0: // empty port1
- default:
- m_data1[0] = 0;
- m_data2[0] = 0;
- break;
- }
-
- switch (ctrl2)
- {
- case 1: // SNES joypad
- input_read_joy(1, FALSE);
- break;
- case 2: // SNES Mouse
- input_read_mouse(1);
- break;
- case 3: // SNES Superscope
- input_read_sscope(1);
- break;
- case 5: // SNES joypad(s) through MP5 multitap
- input_read_joy(1, TRUE);
- multitap1 = TRUE;
- break;
- case 0: // empty port2
- default:
- m_data1[1] = 0;
- m_data2[1] = 0;
- break;
- }
-
- // is automatic reading on? if so, copy port data1/data2 to joy1l->joy4h
- // this actually works like reading the first 16bits from oldjoy1/2 in reverse order
- if (SNES_CPU_REG(NMITIMEN) & 1)
- {
- int shift0 = (multitap0 && !(SNES_CPU_REG(WRIO) & 0x80)) ? 2 : 0;
- int shift1 = (multitap1 && !(SNES_CPU_REG(WRIO) & 0x80)) ? 2 : 0;
-
- SNES_CPU_REG(JOY1L) = (m_data1[0 + shift0] & 0x00ff) >> 0;
- SNES_CPU_REG(JOY1H) = (m_data1[0 + shift0] & 0xff00) >> 8;
- SNES_CPU_REG(JOY2L) = (m_data1[1 + shift1] & 0x00ff) >> 0;
- SNES_CPU_REG(JOY2H) = (m_data1[1 + shift1] & 0xff00) >> 8;
- SNES_CPU_REG(JOY3L) = (m_data2[0 + shift0] & 0x00ff) >> 0;
- SNES_CPU_REG(JOY3H) = (m_data2[0 + shift0] & 0xff00) >> 8;
- SNES_CPU_REG(JOY4L) = (m_data2[1 + shift1] & 0x00ff) >> 0;
- SNES_CPU_REG(JOY4H) = (m_data2[1 + shift1] & 0xff00) >> 8;
-
- // make sure read_idx starts returning all 1s because the auto-read reads it :-)
- m_read_idx[0 + shift0] = 16;
- m_read_idx[1 + shift1] = 16;
- }
-}
-
-UINT8 snes_console_state::oldjoy1_read(int latched)
-{
- UINT8 ctrl1 = ioport("CTRLSEL")->read() & 0x0f;
-
- switch (ctrl1)
- {
- case 1: // SNES joypad
- return input_serial_pad(0, latched, FALSE);
-
- case 2: // SNES Mouse
- return input_serial_mouse(0, latched);
-
- case 3: // SNES Superscope
- return input_serial_sscope(0, latched);
-
- case 5: // SNES multipad
- return input_serial_pad(0, latched, TRUE);
-
- case 0: // empty port1
- default:
- return 0;
- }
-}
-
-UINT8 snes_console_state::oldjoy2_read(int latched)
-{
- UINT8 ctrl2 = (ioport("CTRLSEL")->read() & 0xf0) >> 4;
-
- switch (ctrl2)
- {
- case 1: // SNES joypad
- return input_serial_pad(1, latched, FALSE);
-
- case 2: // SNES Mouse
- return input_serial_mouse(1, latched);
-
- case 3: // SNES Superscope
- return input_serial_sscope(1, latched);
-
- case 5: // SNES multipad
- return input_serial_pad(1, latched, TRUE);
-
- case 0: // empty port1
- default:
- return 0;
- }
-}
-
/*************************************
*
* Machine driver
@@ -1914,25 +1306,6 @@ void snes_console_state::machine_start()
break;
}
- for (int i = 0; i < 2; i++)
- {
- save_item(NAME(m_mouse[i].x), i);
- save_item(NAME(m_mouse[i].oldx), i);
- save_item(NAME(m_mouse[i].y), i);
- save_item(NAME(m_mouse[i].oldy), i);
- save_item(NAME(m_mouse[i].buttons), i);
- save_item(NAME(m_mouse[i].deltax), i);
- save_item(NAME(m_mouse[i].deltay), i);
- save_item(NAME(m_mouse[i].speed), i);
- save_item(NAME(m_scope[i].x), i);
- save_item(NAME(m_scope[i].y), i);
- save_item(NAME(m_scope[i].buttons), i);
- save_item(NAME(m_scope[i].turbo_lock), i);
- save_item(NAME(m_scope[i].pause_lock), i);
- save_item(NAME(m_scope[i].fire_lock), i);
- save_item(NAME(m_scope[i].offscreen), i);
- }
-
if (m_cartslot)
m_cartslot->save_ram();
}
@@ -1964,6 +1337,12 @@ static MACHINE_CONFIG_START( snes, snes_console_state )
MCFG_SNES_PPU_OPENBUS_CB(READ8(snes_state, snes_open_bus_r))
MCFG_VIDEO_SET_SCREEN("screen")
+ MCFG_SNES_CONTROL_PORT_ADD("ctrl1", snes_control_port_devices, "joypad")
+ MCFG_SNESCTRL_ONSCREEN_CB(snes_console_state, onscreen_cb)
+ MCFG_SNES_CONTROL_PORT_ADD("ctrl2", snes_control_port_devices, "joypad")
+ MCFG_SNESCTRL_ONSCREEN_CB(snes_console_state, onscreen_cb)
+ MCFG_SNESCTRL_GUNLATCH_CB(snes_console_state, gun_latch_cb)
+
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("spc700", SNES, 0)