stella/src/common/MouseControl.cxx

265 lines
7.4 KiB
C++

//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "Console.hxx"
#include "Control.hxx"
#include "Paddles.hxx"
#include "Props.hxx"
#include "MouseControl.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MouseControl::MouseControl(Console& console, const string& mode)
: myProps(console.properties()),
myLeftController(console.leftController()),
myRightController(console.rightController()),
myCurrentModeNum(0)
{
istringstream m_axis(mode);
string m_mode;
m_axis >> m_mode;
if(BSPF::equalsIgnoreCase(m_mode, "none"))
{
myModeList.push_back(MouseMode("Mouse input is disabled"));
return;
}
else if(!BSPF::equalsIgnoreCase(m_mode, "auto") && m_mode.length() == 2 &&
m_mode[0] >= '0' && m_mode[0] <= '8' &&
m_mode[1] >= '0' && m_mode[1] <= '8')
{
Axis xaxis = Axis(int(m_mode[0]) - '0');
Axis yaxis = Axis(int(m_mode[1]) - '0');
ostringstream msg;
msg << "Mouse X-axis is ";
Controller::Type xtype = Controller::Joystick, ytype = Controller::Joystick;
int xid = -1, yid = -1;
switch(xaxis)
{
case NoControl:
msg << "not used";
break;
case Paddle0:
xtype = Controller::Paddles;
xid = 0;
msg << "Paddle 0";
break;
case Paddle1:
xtype = Controller::Paddles;
xid = 1;
msg << "Paddle 1";
break;
case Paddle2:
xtype = Controller::Paddles;
xid = 2;
msg << "Paddle 2";
break;
case Paddle3:
xtype = Controller::Paddles;
xid = 3;
msg << "Paddle 3";
break;
case Driving0:
xtype = Controller::Driving;
xid = 0;
msg << "Driving 0";
break;
case Driving1:
xtype = Controller::Driving;
xid = 1;
msg << "Driving 1";
break;
case MindLink0:
xtype = Controller::MindLink;
xid = 0;
msg << "MindLink 0";
break;
case MindLink1:
xtype = Controller::MindLink;
xid = 1;
msg << "MindLink 1";
break;
}
msg << ", Y-axis is ";
switch(yaxis)
{
case NoControl:
msg << "not used";
break;
case Paddle0:
ytype = Controller::Paddles;
yid = 0;
msg << "Paddle 0";
break;
case Paddle1:
ytype = Controller::Paddles;
yid = 1;
msg << "Paddle 1";
break;
case Paddle2:
ytype = Controller::Paddles;
yid = 2;
msg << "Paddle 2";
break;
case Paddle3:
ytype = Controller::Paddles;
yid = 3;
msg << "Paddle 3";
break;
case Driving0:
ytype = Controller::Driving;
yid = 0;
msg << "Driving 0";
break;
case Driving1:
ytype = Controller::Driving;
yid = 1;
msg << "Driving 1";
break;
case MindLink0:
ytype = Controller::MindLink;
yid = 0;
msg << "MindLink 0";
break;
case MindLink1:
ytype = Controller::MindLink;
yid = 1;
msg << "MindLink 1";
break;
}
myModeList.push_back(MouseMode(xtype, xid, ytype, yid, msg.str()));
}
// Now consider the possible modes for the mouse based on the left
// and right controllers
bool noswap = BSPF::equalsIgnoreCase(myProps.get(Console_SwapPorts), "NO");
if(noswap)
{
addLeftControllerModes(noswap);
addRightControllerModes(noswap);
}
else
{
addRightControllerModes(noswap);
addLeftControllerModes(noswap);
}
// Set range information (currently only for paddles, but may be used
// for other controllers in the future)
int m_range = 100;
if(!(m_axis >> m_range))
m_range = 100;
Paddles::setPaddleRange(m_range);
// If the mouse isn't used at all, we still need one item in the list
if(myModeList.size() == 0)
myModeList.push_back(MouseMode("Mouse not used for current controllers"));
#if 0
for(const auto& m: myModeList)
cerr << m << endl;
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& MouseControl::next()
{
const MouseMode& mode = myModeList[myCurrentModeNum];
myCurrentModeNum = (myCurrentModeNum + 1) % myModeList.size();
myLeftController.setMouseControl(mode.xtype, mode.xid, mode.ytype, mode.yid);
myRightController.setMouseControl(mode.xtype, mode.xid, mode.ytype, mode.yid);
return mode.message;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MouseControl::addLeftControllerModes(bool noswap)
{
if(controllerSupportsMouse(myLeftController))
{
if(myLeftController.type() == Controller::Paddles)
{
if(noswap) addPaddleModes(0, 1, 0, 1);
else addPaddleModes(2, 3, 0, 1);
}
else
{
ostringstream msg;
msg << "Mouse is left " << myLeftController.name() << " controller";
Controller::Type type = myLeftController.type();
int id = noswap ? 0 : 1;
myModeList.push_back(MouseMode(type, id, type, id, msg.str()));
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MouseControl::addRightControllerModes(bool noswap)
{
if(controllerSupportsMouse(myRightController))
{
if(myRightController.type() == Controller::Paddles)
{
if(noswap) addPaddleModes(2, 3, 2, 3);
else addPaddleModes(0, 1, 2, 3);
}
else
{
ostringstream msg;
msg << "Mouse is right " << myRightController.name() << " controller";
Controller::Type type = myRightController.type();
int id = noswap ? 1 : 0;
myModeList.push_back(MouseMode(type, id, type, id, msg.str()));
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MouseControl::addPaddleModes(int lport, int rport, int lname, int rname)
{
Controller::Type type = Controller::Paddles;
ostringstream msg;
msg << "Mouse is Paddle " << lname << " controller";
MouseMode mode0(type, lport, type, lport, msg.str());
msg.str("");
msg << "Mouse is Paddle " << rname << " controller";
MouseMode mode1(type, rport, type, rport, msg.str());
if(BSPF::equalsIgnoreCase(myProps.get(Controller_SwapPaddles), "NO"))
{
myModeList.push_back(mode0);
myModeList.push_back(mode1);
}
else
{
myModeList.push_back(mode1);
myModeList.push_back(mode0);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool MouseControl::controllerSupportsMouse(Controller& controller)
{
// Test whether the controller uses the mouse at all
// We can pass in dummy values here, since the controllers will be
// initialized by a call to next() once the system is up and running
return controller.setMouseControl(
Controller::Joystick, -1, Controller::Joystick, -1);
}