mirror of https://github.com/stella-emu/stella.git
added default mapping controller port option (resolves #897)
This commit is contained in:
parent
55e3874097
commit
f7e46338b8
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
* Enhanced Kid Vid support to play tape audio.
|
* Enhanced Kid Vid support to play tape audio.
|
||||||
|
|
||||||
|
* Added port selection, used for controller default mapping
|
||||||
|
|
||||||
* Added missing PlusROM support for E7 bankswitching.
|
* Added missing PlusROM support for E7 bankswitching.
|
||||||
|
|
||||||
* Acclerated emulation up to ~15% (ARM).
|
* Acclerated emulation up to ~15% (ARM).
|
||||||
|
|
|
@ -4041,7 +4041,7 @@
|
||||||
<tr><td>Allow all 4 directions ...</td><td>Allow all 4 joystick directions to be pressed simultaneously</td><td>-joyallow4</td></tr>
|
<tr><td>Allow all 4 directions ...</td><td>Allow all 4 joystick directions to be pressed simultaneously</td><td>-joyallow4</td></tr>
|
||||||
<tr><td>Use modifier key combos</td><td>Enable using modifier keys in keyboard actions</td><td>-modcombo</td></tr>
|
<tr><td>Use modifier key combos</td><td>Enable using modifier keys in keyboard actions</td><td>-modcombo</td></tr>
|
||||||
<tr><td>Swap Stelladaptor ports</td><td>Swap the order of the detected Stelladaptors/2600-daptors (see <b>Advanced Configuration - <a href="#Adaptor">Stelladaptor/2600-daptor Support</a></b>)</td><td>-saport</td></tr>
|
<tr><td>Swap Stelladaptor ports</td><td>Swap the order of the detected Stelladaptors/2600-daptors (see <b>Advanced Configuration - <a href="#Adaptor">Stelladaptor/2600-daptor Support</a></b>)</td><td>-saport</td></tr>
|
||||||
<tr><td>Controller Database</td><td>Show all controllers that Stella knows about, with the option to remove them</td><td> </td></tr>
|
<tr><td>Controller Database</td><td>Show all controllers that Stella knows about and allow assigning them to a default mapping port and removing them</td><td> </td></tr>
|
||||||
<tr><td>Erase EEPROM</td><td>Erase the whole AtariVox/SaveKey flash memory</td><td> </td></tr>
|
<tr><td>Erase EEPROM</td><td>Erase the whole AtariVox/SaveKey flash memory</td><td> </td></tr>
|
||||||
<tr><td>AtariVox serial port</td><td>Described in further detail in <b>Advanced Configuration - <a href="#AtariVox">AtariVox/SaveKey Support</a></b> </td><td>-avoxport</td></tr>
|
<tr><td>AtariVox serial port</td><td>Described in further detail in <b>Advanced Configuration - <a href="#AtariVox">AtariVox/SaveKey Support</a></b> </td><td>-avoxport</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -228,6 +228,17 @@ bool PhysicalJoystickHandler::remove(string_view name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void PhysicalJoystickHandler::setPort(string_view name, PhysicalJoystick::Port port)
|
||||||
|
{
|
||||||
|
const auto it = myDatabase.find(name);
|
||||||
|
if(it != myDatabase.end() && it->second.joy != nullptr)
|
||||||
|
{
|
||||||
|
it->second.joy->setPort(port);
|
||||||
|
// TODO: update mappings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool PhysicalJoystickHandler::mapStelladaptors(string_view saport, int ID)
|
bool PhysicalJoystickHandler::mapStelladaptors(string_view saport, int ID)
|
||||||
{
|
{
|
||||||
|
@ -359,35 +370,42 @@ void PhysicalJoystickHandler::setStickDefaultMapping(
|
||||||
|
|
||||||
if(j)
|
if(j)
|
||||||
{
|
{
|
||||||
switch (mode)
|
switch(mode)
|
||||||
{
|
{
|
||||||
case EventMode::kEmulationMode:
|
case EventMode::kEmulationMode:
|
||||||
{
|
{
|
||||||
// A regular joystick defaults to left or right based on the
|
// A regular joystick defaults to left or right based on
|
||||||
// stick number being even or odd; 'daptor joysticks request a
|
// the defined port or stick number being even or odd;
|
||||||
// specific port
|
// 'daptor' joysticks request a specific port
|
||||||
const bool useLeftMappings =
|
bool useLeftMappings;
|
||||||
j->type == PhysicalJoystick::Type::REGULAR ? ((stick % 2) == 0) :
|
if(j->type == PhysicalJoystick::Type::REGULAR)
|
||||||
(j->type == PhysicalJoystick::Type::LEFT_STELLADAPTOR ||
|
{
|
||||||
j->type == PhysicalJoystick::Type::LEFT_2600DAPTOR);
|
useLeftMappings = j->port == PhysicalJoystick::Port::LEFT
|
||||||
|
|| (j->port == PhysicalJoystick::Port::AUTO && (stick % 2) == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
useLeftMappings =
|
||||||
|
j->type == PhysicalJoystick::Type::LEFT_STELLADAPTOR ||
|
||||||
|
j->type == PhysicalJoystick::Type::LEFT_2600DAPTOR;
|
||||||
|
|
||||||
if(useLeftMappings)
|
if(useLeftMappings)
|
||||||
{
|
{
|
||||||
// put all controller events into their own mode's mappings
|
// put all controller events into their own mode's mappings
|
||||||
for (const auto& item : DefaultLeftJoystickMapping)
|
for(const auto& item : DefaultLeftJoystickMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kJoystickMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kJoystickMode, updateDefaults);
|
||||||
for (const auto& item : DefaultLeftKeyboardMapping)
|
for(const auto& item : DefaultLeftKeyboardMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kKeyboardMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kKeyboardMode, updateDefaults);
|
||||||
for (const auto& item : DefaultLeftDrivingMapping)
|
for(const auto& item : DefaultLeftDrivingMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// put all controller events into their own mode's mappings
|
// put all controller events into their own mode's mappings
|
||||||
for (const auto& item : DefaultRightJoystickMapping)
|
for(const auto& item : DefaultRightJoystickMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kJoystickMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kJoystickMode, updateDefaults);
|
||||||
for (const auto& item : DefaultRightKeyboardMapping)
|
for(const auto& item : DefaultRightKeyboardMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kKeyboardMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kKeyboardMode, updateDefaults);
|
||||||
for (const auto& item : DefaultRightDrivingMapping)
|
for(const auto& item : DefaultRightDrivingMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,16 +422,16 @@ void PhysicalJoystickHandler::setStickDefaultMapping(
|
||||||
// and 2600-daptors support two players natively.
|
// and 2600-daptors support two players natively.
|
||||||
const int paddlesPerJoystick = (j->type == PhysicalJoystick::Type::REGULAR && !retron77) ? 1 : 2;
|
const int paddlesPerJoystick = (j->type == PhysicalJoystick::Type::REGULAR && !retron77) ? 1 : 2;
|
||||||
|
|
||||||
if( paddlesPerJoystick == 2 )
|
if(paddlesPerJoystick == 2)
|
||||||
{
|
{
|
||||||
if( useLeftMappings )
|
if(useLeftMappings)
|
||||||
{
|
{
|
||||||
for (const auto& item : DefaultLeftPaddlesMapping)
|
for(const auto& item : DefaultLeftPaddlesMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const auto& item : DefaultRightPaddlesMapping)
|
for(const auto& item : DefaultRightPaddlesMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,29 +448,29 @@ void PhysicalJoystickHandler::setStickDefaultMapping(
|
||||||
const bool useLeftPaddleMappings = (stick % 4) < 2;
|
const bool useLeftPaddleMappings = (stick % 4) < 2;
|
||||||
const bool useAPaddleMappings = (stick % 2) == 0;
|
const bool useAPaddleMappings = (stick % 2) == 0;
|
||||||
|
|
||||||
if( useLeftPaddleMappings )
|
if(useLeftPaddleMappings)
|
||||||
{
|
{
|
||||||
if( useAPaddleMappings )
|
if(useAPaddleMappings)
|
||||||
{
|
{
|
||||||
for (const auto& item : DefaultLeftAPaddlesMapping)
|
for(const auto& item : DefaultLeftAPaddlesMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const auto& item : DefaultLeftBPaddlesMapping)
|
for(const auto& item : DefaultLeftBPaddlesMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( useAPaddleMappings )
|
if(useAPaddleMappings)
|
||||||
{
|
{
|
||||||
for (const auto& item : DefaultRightAPaddlesMapping)
|
for(const auto& item : DefaultRightAPaddlesMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const auto& item : DefaultRightBPaddlesMapping)
|
for(const auto& item : DefaultRightBPaddlesMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,7 +484,7 @@ void PhysicalJoystickHandler::setStickDefaultMapping(
|
||||||
}
|
}
|
||||||
|
|
||||||
case EventMode::kMenuMode:
|
case EventMode::kMenuMode:
|
||||||
for (const auto& item : DefaultMenuMapping)
|
for(const auto& item : DefaultMenuMapping)
|
||||||
setDefaultAction(stick, item, event, EventMode::kMenuMode, updateDefaults);
|
setDefaultAction(stick, item, event, EventMode::kMenuMode, updateDefaults);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1071,13 +1089,19 @@ void PhysicalJoystickHandler::handleHatEvent(int stick, int hat, int value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
VariantList PhysicalJoystickHandler::database() const
|
PhysicalJoystickHandler::MinStrickInfoList PhysicalJoystickHandler::minStickList() const
|
||||||
{
|
{
|
||||||
VariantList db;
|
MinStrickInfoList list;
|
||||||
for(const auto& [_name, _info]: myDatabase)
|
|
||||||
VarList::push_back(db, _name, _info.joy ? _info.joy->ID : -1);
|
|
||||||
|
|
||||||
return db;
|
for(const auto& [_name, _info] : myDatabase)
|
||||||
|
{
|
||||||
|
MinStrickInfo stick(_name,
|
||||||
|
_info.joy ? _info.joy->ID : -1,
|
||||||
|
_info.joy ? _info.joy->port : PhysicalJoystick::Port::AUTO);
|
||||||
|
|
||||||
|
list.push_back(stick);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -46,6 +46,18 @@ using PhysicalJoystickPtr = shared_ptr<PhysicalJoystick>;
|
||||||
*/
|
*/
|
||||||
class PhysicalJoystickHandler
|
class PhysicalJoystickHandler
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
struct MinStrickInfo
|
||||||
|
{
|
||||||
|
string name;
|
||||||
|
int ID;
|
||||||
|
PhysicalJoystick::Port port;
|
||||||
|
|
||||||
|
explicit MinStrickInfo(string _name, int _id, PhysicalJoystick::Port _port)
|
||||||
|
: name{_name}, ID{_id}, port{_port} {}
|
||||||
|
};
|
||||||
|
using MinStrickInfoList = std::vector<MinStrickInfo>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct StickInfo
|
struct StickInfo
|
||||||
{
|
{
|
||||||
|
@ -74,6 +86,7 @@ class PhysicalJoystickHandler
|
||||||
int add(const PhysicalJoystickPtr& stick);
|
int add(const PhysicalJoystickPtr& stick);
|
||||||
bool remove(int id);
|
bool remove(int id);
|
||||||
bool remove(string_view name);
|
bool remove(string_view name);
|
||||||
|
void setPort(string_view name, PhysicalJoystick::Port port);
|
||||||
bool mapStelladaptors(string_view saport, int ID = -1);
|
bool mapStelladaptors(string_view saport, int ID = -1);
|
||||||
bool hasStelladaptors() const;
|
bool hasStelladaptors() const;
|
||||||
void setDefaultMapping(Event::Type event, EventMode mode);
|
void setDefaultMapping(Event::Type event, EventMode mode);
|
||||||
|
@ -112,8 +125,8 @@ class PhysicalJoystickHandler
|
||||||
return j->joyMap.get(mode, button, hat, hatDir);
|
return j->joyMap.get(mode, button, hat, hatDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a list of pairs consisting of joystick name and associated ID. */
|
/** Returns a list containing minimal controller info (name, ID, port). */
|
||||||
VariantList database() const;
|
MinStrickInfoList minStickList() const;
|
||||||
|
|
||||||
void changeDigitalDeadZone(int direction = +1);
|
void changeDigitalDeadZone(int direction = +1);
|
||||||
void changeAnalogPaddleDeadZone(int direction = +1);
|
void changeAnalogPaddleDeadZone(int direction = +1);
|
||||||
|
|
|
@ -221,7 +221,7 @@ void PhysicalKeyboardHandler::defineControllerMappings(
|
||||||
const Controller::Type type, Controller::Jack port, const Properties& properties)
|
const Controller::Type type, Controller::Jack port, const Properties& properties)
|
||||||
{
|
{
|
||||||
// Determine controller events to use
|
// Determine controller events to use
|
||||||
if(type == Controller::Type::QuadTari)
|
if(type == Controller::Type::QuadTari)
|
||||||
{
|
{
|
||||||
if(port == Controller::Jack::Left)
|
if(port == Controller::Jack::Left)
|
||||||
{
|
{
|
||||||
|
@ -233,7 +233,7 @@ void PhysicalKeyboardHandler::defineControllerMappings(
|
||||||
myRightMode = getMode(properties, PropType::Controller_Right1);
|
myRightMode = getMode(properties, PropType::Controller_Right1);
|
||||||
myRight2ndMode = getMode(properties, PropType::Controller_Right2);
|
myRight2ndMode = getMode(properties, PropType::Controller_Right2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const EventMode mode = getMode(type);
|
const EventMode mode = getMode(type);
|
||||||
|
@ -459,7 +459,7 @@ bool PhysicalKeyboardHandler::isDrivingEvent(const Event::Type event)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool PhysicalKeyboardHandler::isCommonEvent(const Event::Type event)
|
bool PhysicalKeyboardHandler::isCommonEvent(const Event::Type event)
|
||||||
{
|
{
|
||||||
return !(isJoystickEvent(event) || isPaddleEvent(event)
|
return !(isJoystickEvent(event) || isPaddleEvent(event)
|
||||||
|| isKeyboardEvent(event) || isDrivingEvent(event));
|
|| isKeyboardEvent(event) || isDrivingEvent(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ json PhysicalJoystick::getMap() const
|
||||||
json mapping = json::object();
|
json mapping = json::object();
|
||||||
|
|
||||||
mapping["name"] = name;
|
mapping["name"] = name;
|
||||||
|
mapping["port"] = getName(port);
|
||||||
|
|
||||||
for (const auto& mode: {
|
for (const auto& mode: {
|
||||||
EventMode::kMenuMode, EventMode::kJoystickMode, EventMode::kPaddlesMode, EventMode::kKeyboardMode, EventMode::kDrivingMode, EventMode::kCommonMode
|
EventMode::kMenuMode, EventMode::kJoystickMode, EventMode::kPaddlesMode, EventMode::kKeyboardMode, EventMode::kDrivingMode, EventMode::kCommonMode
|
||||||
|
@ -84,14 +85,19 @@ bool PhysicalJoystick::setMap(const json& map)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (const auto& entry: map.items()) {
|
for (const auto& entry: map.items()) {
|
||||||
if (entry.key() == "name") continue;
|
if (entry.key() == "name")
|
||||||
|
continue;
|
||||||
|
if(entry.key() == "port")
|
||||||
|
{
|
||||||
|
port = getPort(entry.value());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
joyMap.loadMapping(entry.value(), eventModeFromJsonName(entry.key()));
|
joyMap.loadMapping(entry.value(), eventModeFromJsonName(entry.key()));
|
||||||
} catch (const json::exception&) {
|
} catch (const json::exception&) {
|
||||||
Logger::error("ignoring invalid json mapping for " + entry.key());
|
Logger::error("ignoring invalid json mapping for " + entry.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +113,34 @@ bool PhysicalJoystick::setMap(const json& map)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string PhysicalJoystick::getName(const PhysicalJoystick::Port _port) const
|
||||||
|
{
|
||||||
|
static constexpr std::array<string_view,
|
||||||
|
static_cast<int>(PhysicalJoystick::Port::NUM_PORTS)> NAMES =
|
||||||
|
{
|
||||||
|
"Auto", "Left", "Right"
|
||||||
|
};
|
||||||
|
|
||||||
|
return string{NAMES[static_cast<int>(_port)]};
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
PhysicalJoystick::Port PhysicalJoystick::getPort(string_view portName) const
|
||||||
|
{
|
||||||
|
static constexpr std::array<string_view,
|
||||||
|
static_cast<int>(PhysicalJoystick::Port::NUM_PORTS)> NAMES =
|
||||||
|
{
|
||||||
|
"Auto", "Left", "Right"
|
||||||
|
};
|
||||||
|
|
||||||
|
for(int i = 0; i < static_cast<int>(PhysicalJoystick::Port::NUM_PORTS); ++i)
|
||||||
|
if (BSPF::equalsIgnoreCase(portName, NAMES[i]))
|
||||||
|
return PhysicalJoystick::Port{i};
|
||||||
|
|
||||||
|
return PhysicalJoystick::Port::AUTO;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
json PhysicalJoystick::convertLegacyMapping(string_view mapping, string_view name)
|
json PhysicalJoystick::convertLegacyMapping(string_view mapping, string_view name)
|
||||||
{
|
{
|
||||||
|
@ -167,7 +201,22 @@ void PhysicalJoystick::getValues(string_view list, IntArray& map)
|
||||||
string PhysicalJoystick::about() const
|
string PhysicalJoystick::about() const
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "'" << name << "' with: " << numAxes << " axes, " << numButtons << " buttons, "
|
|
||||||
|
buf << "'" << name << "' in ";
|
||||||
|
switch(port)
|
||||||
|
{
|
||||||
|
case Port::LEFT:
|
||||||
|
buf << "left";
|
||||||
|
break;
|
||||||
|
case Port::RIGHT:
|
||||||
|
buf << "right";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buf << "auto";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf << " port with: "
|
||||||
|
<< numAxes << " axes, " << numButtons << " buttons, "
|
||||||
<< numHats << " hats";
|
<< numHats << " hats";
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
|
|
|
@ -43,10 +43,18 @@ class PhysicalJoystick
|
||||||
static constexpr char MODE_DELIM = '>'; // must not be '^', '|' or '#'
|
static constexpr char MODE_DELIM = '>'; // must not be '^', '|' or '#'
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class Port {
|
||||||
|
AUTO,
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
NUM_PORTS
|
||||||
|
};
|
||||||
|
|
||||||
PhysicalJoystick() = default;
|
PhysicalJoystick() = default;
|
||||||
|
|
||||||
nlohmann::json getMap() const;
|
nlohmann::json getMap() const;
|
||||||
bool setMap(const nlohmann::json& map);
|
bool setMap(const nlohmann::json& map);
|
||||||
|
void setPort(const Port _port) { port = _port; }
|
||||||
|
|
||||||
static nlohmann::json convertLegacyMapping(string_view mapping,
|
static nlohmann::json convertLegacyMapping(string_view mapping,
|
||||||
string_view name);
|
string_view name);
|
||||||
|
@ -69,6 +77,7 @@ class PhysicalJoystick
|
||||||
Type type{Type::REGULAR};
|
Type type{Type::REGULAR};
|
||||||
int ID{-1};
|
int ID{-1};
|
||||||
string name{"None"};
|
string name{"None"};
|
||||||
|
Port port{Port::AUTO};
|
||||||
int numAxes{0}, numButtons{0}, numHats{0};
|
int numAxes{0}, numButtons{0}, numHats{0};
|
||||||
IntArray axisLastValue;
|
IntArray axisLastValue;
|
||||||
IntArray buttonLast;
|
IntArray buttonLast;
|
||||||
|
@ -79,6 +88,10 @@ class PhysicalJoystick
|
||||||
private:
|
private:
|
||||||
static void getValues(string_view list, IntArray& map);
|
static void getValues(string_view list, IntArray& map);
|
||||||
|
|
||||||
|
// Convert from string to Port type and vice versa
|
||||||
|
string getName(const Port _port) const;
|
||||||
|
Port getPort(string_view portName) const;
|
||||||
|
|
||||||
friend ostream& operator<<(ostream& os, const PhysicalJoystick& s) {
|
friend ostream& operator<<(ostream& os, const PhysicalJoystick& s) {
|
||||||
os << " ID: " << s.ID << ", name: " << s.name << ", numaxis: " << s.numAxes
|
os << " ID: " << s.ID << ", name: " << s.name << ", numaxis: " << s.numAxes
|
||||||
<< ", numbtns: " << s.numButtons << ", numhats: " << s.numHats;
|
<< ", numbtns: " << s.numButtons << ", numhats: " << s.numHats;
|
||||||
|
|
|
@ -84,7 +84,7 @@ class Event
|
||||||
|
|
||||||
UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown,
|
UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown,
|
||||||
UISelect, UINavPrev, UINavNext, UIOK, UICancel, UIPrevDir,
|
UISelect, UINavPrev, UINavNext, UIOK, UICancel, UIPrevDir,
|
||||||
UITabPrev, UITabNext,
|
UITabPrev, UITabNext, UIReload,
|
||||||
|
|
||||||
NextMouseControl, ToggleGrabMouse,
|
NextMouseControl, ToggleGrabMouse,
|
||||||
MouseAxisXMove, MouseAxisYMove, MouseAxisXValue, MouseAxisYValue,
|
MouseAxisXMove, MouseAxisYMove, MouseAxisXValue, MouseAxisYValue,
|
||||||
|
|
|
@ -169,6 +169,9 @@ void EventHandler::addPhysicalJoystick(const PhysicalJoystickPtr& joy)
|
||||||
|
|
||||||
setActionMappings(EventMode::kEmulationMode);
|
setActionMappings(EventMode::kEmulationMode);
|
||||||
setActionMappings(EventMode::kMenuMode);
|
setActionMappings(EventMode::kMenuMode);
|
||||||
|
|
||||||
|
if(myOverlay)
|
||||||
|
myOverlay->handleEvent(Event::UIReload);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +180,9 @@ void EventHandler::removePhysicalJoystick(int id)
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
myPJoyHandler->remove(id);
|
myPJoyHandler->remove(id);
|
||||||
|
|
||||||
|
if(myOverlay)
|
||||||
|
myOverlay->handleEvent(Event::UIReload);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2078,6 +2084,15 @@ void EventHandler::removePhysicalJoystickFromDatabase(string_view name)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::setPhysicalJoystickPortInDatabase(string_view name,
|
||||||
|
PhysicalJoystick::Port port)
|
||||||
|
{
|
||||||
|
#ifdef JOYSTICK_SUPPORT
|
||||||
|
myPJoyHandler->setPort(name, port);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool EventHandler::addKeyMapping(Event::Type event, EventMode mode, StellaKey key, StellaMod mod)
|
bool EventHandler::addKeyMapping(Event::Type event, EventMode mode, StellaKey key, StellaMod mod)
|
||||||
{
|
{
|
||||||
|
|
|
@ -333,11 +333,10 @@ class EventHandler
|
||||||
bool hasOverlay() const { return myOverlay != nullptr; }
|
bool hasOverlay() const { return myOverlay != nullptr; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return a list of all physical joysticks currently in the internal database
|
Return a simple list of all physical joysticks currently in the internal database
|
||||||
(first part of variant) and its internal ID (second part of variant).
|
|
||||||
*/
|
*/
|
||||||
VariantList physicalJoystickDatabase() const {
|
PhysicalJoystickHandler::MinStrickInfoList physicalJoystickList() const {
|
||||||
return myPJoyHandler->database();
|
return myPJoyHandler->minStickList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -346,6 +345,12 @@ class EventHandler
|
||||||
*/
|
*/
|
||||||
void removePhysicalJoystickFromDatabase(string_view name);
|
void removePhysicalJoystickFromDatabase(string_view name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Change the port of the physical joystick identified by 'name' in
|
||||||
|
the joystick database, only if it is not currently active.
|
||||||
|
*/
|
||||||
|
void setPhysicalJoystickPortInDatabase(string_view name, PhysicalJoystick::Port port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enable/disable text events (distinct from single-key events).
|
Enable/disable text events (distinct from single-key events).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -168,6 +168,7 @@ class Dialog : public GuiObject
|
||||||
virtual void handleJoyUp(int stick, int button);
|
virtual void handleJoyUp(int stick, int button);
|
||||||
virtual void handleJoyAxis(int stick, JoyAxis axis, JoyDir adir, int button = JOY_CTRL_NONE);
|
virtual void handleJoyAxis(int stick, JoyAxis axis, JoyDir adir, int button = JOY_CTRL_NONE);
|
||||||
virtual bool handleJoyHat(int stick, int hat, JoyHatDir hdir, int button = JOY_CTRL_NONE);
|
virtual bool handleJoyHat(int stick, int hat, JoyHatDir hdir, int button = JOY_CTRL_NONE);
|
||||||
|
virtual void handleEvent(Event::Type event) {};
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
virtual Event::Type getJoyAxisEvent(int stick, JoyAxis axis, JoyDir adir, int button);
|
virtual Event::Type getJoyAxisEvent(int stick, JoyAxis axis, JoyDir adir, int button);
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,18 @@ void DialogContainer::handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int
|
||||||
activeDialog->handleJoyHat(stick, hat, hdir, button);
|
activeDialog->handleJoyHat(stick, hat, hdir, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DialogContainer::handleEvent(Event::Type event)
|
||||||
|
{
|
||||||
|
if(myDialogStack.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Send the event to the dialog box on the top of the stack
|
||||||
|
Dialog* activeDialog = myDialogStack.top();
|
||||||
|
|
||||||
|
activeDialog->handleEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void DialogContainer::reset()
|
void DialogContainer::reset()
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ class OSystem;
|
||||||
class EventHandler;
|
class EventHandler;
|
||||||
|
|
||||||
#include "EventHandlerConstants.hxx"
|
#include "EventHandlerConstants.hxx"
|
||||||
|
#include "Event.hxx"
|
||||||
#include "StellaKeys.hxx"
|
#include "StellaKeys.hxx"
|
||||||
#include "Stack.hxx"
|
#include "Stack.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
@ -119,6 +120,13 @@ class DialogContainer
|
||||||
*/
|
*/
|
||||||
void handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int button);
|
void handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Handle an arbitray dialog event.
|
||||||
|
|
||||||
|
@param event The send event
|
||||||
|
*/
|
||||||
|
void handleEvent(Event::Type event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Tick the dialog and all its widgets.
|
Tick the dialog and all its widgets.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Widget.hxx"
|
#include "Widget.hxx"
|
||||||
#include "Font.hxx"
|
#include "Font.hxx"
|
||||||
#include "EditTextWidget.hxx"
|
#include "EditTextWidget.hxx"
|
||||||
|
#include "PopUpWidget.hxx"
|
||||||
#include "StringListWidget.hxx"
|
#include "StringListWidget.hxx"
|
||||||
#include "Variant.hxx"
|
#include "Variant.hxx"
|
||||||
#include "JoystickDialog.hxx"
|
#include "JoystickDialog.hxx"
|
||||||
|
@ -47,12 +48,23 @@ JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font,
|
||||||
|
|
||||||
// Joystick ID
|
// Joystick ID
|
||||||
ypos = _h - VBORDER - (buttonHeight + lineHeight) / 2;
|
ypos = _h - VBORDER - (buttonHeight + lineHeight) / 2;
|
||||||
auto* t = new StaticTextWidget(this, font, xpos, ypos+2, "Controller ID ");
|
auto* t = new StaticTextWidget(this, font, xpos, ypos, "Controller ID ");
|
||||||
xpos += t->getWidth();
|
xpos += t->getWidth();
|
||||||
myJoyText = new EditTextWidget(this, font, xpos, ypos,
|
myJoyText = new EditTextWidget(this, font, xpos, ypos - 2,
|
||||||
font.getStringWidth("Unplugged "), font.getLineHeight(), "");
|
font.getStringWidth("Unplugged "), lineHeight, "");
|
||||||
myJoyText->setEditable(false);
|
myJoyText->setEditable(false);
|
||||||
|
|
||||||
|
// Port
|
||||||
|
VariantList ports;
|
||||||
|
VarList::push_back(ports, "Auto", static_cast<Int32>(PhysicalJoystick::Port::AUTO));
|
||||||
|
VarList::push_back(ports, "Left", static_cast<Int32>(PhysicalJoystick::Port::LEFT));
|
||||||
|
VarList::push_back(ports, "Right", static_cast<Int32>(PhysicalJoystick::Port::RIGHT));
|
||||||
|
|
||||||
|
myJoyPort = new PopUpWidget(this, font, myJoyText->getRight() + fontWidth * 2, ypos - 1,
|
||||||
|
font.getStringWidth("Right"), lineHeight, ports, "Port ", 0, kPortCmd);
|
||||||
|
myJoyPort->setToolTip("Define default mapping port.");
|
||||||
|
wid.push_back(myJoyPort);
|
||||||
|
|
||||||
// Add buttons at bottom
|
// Add buttons at bottom
|
||||||
xpos = _w - buttonWidth - HBORDER;
|
xpos = _w - buttonWidth - HBORDER;
|
||||||
ypos = _h - VBORDER - buttonHeight;
|
ypos = _h - VBORDER - buttonHeight;
|
||||||
|
@ -77,10 +89,11 @@ void JoystickDialog::loadConfig()
|
||||||
myJoyIDs.clear();
|
myJoyIDs.clear();
|
||||||
|
|
||||||
StringList sticks;
|
StringList sticks;
|
||||||
for(const auto& [_name, _id]: instance().eventHandler().physicalJoystickDatabase())
|
for(const auto& _entry : instance().eventHandler().physicalJoystickList())
|
||||||
{
|
{
|
||||||
sticks.push_back(_name);
|
sticks.push_back(_entry.name);
|
||||||
myJoyIDs.push_back(_id.toInt());
|
myJoyIDs.push_back(_entry.ID);
|
||||||
|
myJoyPorts.push_back(static_cast<int>(_entry.port));
|
||||||
}
|
}
|
||||||
myJoyList->setList(sticks);
|
myJoyList->setList(sticks);
|
||||||
myJoyList->setSelected(0);
|
myJoyList->setSelected(0);
|
||||||
|
@ -91,6 +104,13 @@ void JoystickDialog::loadConfig()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void JoystickDialog::handleEvent(Event::Type event)
|
||||||
|
{
|
||||||
|
if(event == Event::Type::UIReload)
|
||||||
|
loadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||||
{
|
{
|
||||||
|
@ -100,6 +120,13 @@ void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kPortCmd:
|
||||||
|
myJoyPorts[myJoyList->getSelected()] = myJoyPort->getSelected();
|
||||||
|
instance().eventHandler().setPhysicalJoystickPortInDatabase(
|
||||||
|
myJoyList->getSelectedString(),
|
||||||
|
static_cast<PhysicalJoystick::Port>(myJoyPort->getSelected()));
|
||||||
|
break;
|
||||||
|
|
||||||
case kRemoveCmd:
|
case kRemoveCmd:
|
||||||
instance().eventHandler().removePhysicalJoystickFromDatabase(
|
instance().eventHandler().removePhysicalJoystickFromDatabase(
|
||||||
myJoyList->getSelectedString());
|
myJoyList->getSelectedString());
|
||||||
|
@ -107,20 +134,24 @@ void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ListWidget::kSelectionChangedCmd:
|
case ListWidget::kSelectionChangedCmd:
|
||||||
if(myJoyIDs[data] >= 0)
|
{
|
||||||
|
const bool isPlugged = myJoyIDs[data] >= 0;
|
||||||
|
if(isPlugged)
|
||||||
{
|
{
|
||||||
myRemoveBtn->setEnabled(false);
|
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "C" << myJoyIDs[data];
|
buf << "C" << myJoyIDs[data];
|
||||||
myJoyText->setText(buf.str());
|
myJoyText->setText(buf.str());
|
||||||
|
myJoyPort->setSelected(myJoyPorts[data]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myRemoveBtn->setEnabled(true);
|
|
||||||
myJoyText->setText("Unplugged");
|
myJoyText->setText("Unplugged");
|
||||||
|
myJoyPort->setText("");
|
||||||
}
|
}
|
||||||
|
myJoyPort->setEnabled(isPlugged);
|
||||||
|
myRemoveBtn->setEnabled(!isPlugged);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
Dialog::handleCommand(sender, cmd, data, id);
|
Dialog::handleCommand(sender, cmd, data, id);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -22,6 +22,7 @@ class CommandSender;
|
||||||
class GuiObject;
|
class GuiObject;
|
||||||
class ButtonWidget;
|
class ButtonWidget;
|
||||||
class EditTextWidgetWidget;
|
class EditTextWidgetWidget;
|
||||||
|
class PopUpWidget;
|
||||||
class StringListWidget;
|
class StringListWidget;
|
||||||
|
|
||||||
#include "Dialog.hxx"
|
#include "Dialog.hxx"
|
||||||
|
@ -43,17 +44,23 @@ class JoystickDialog : public Dialog
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
void loadConfig() override;
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
void handleEvent(Event::Type event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringListWidget* myJoyList{nullptr};
|
StringListWidget* myJoyList{nullptr};
|
||||||
EditTextWidget* myJoyText{nullptr};
|
EditTextWidget* myJoyText{nullptr};
|
||||||
|
PopUpWidget* myJoyPort{nullptr};
|
||||||
|
|
||||||
ButtonWidget* myRemoveBtn{nullptr};
|
ButtonWidget* myRemoveBtn{nullptr};
|
||||||
ButtonWidget* myCloseBtn{nullptr};
|
ButtonWidget* myCloseBtn{nullptr};
|
||||||
|
|
||||||
IntArray myJoyIDs;
|
IntArray myJoyIDs;
|
||||||
|
IntArray myJoyPorts;
|
||||||
|
|
||||||
enum { kRemoveCmd = 'JDrm' };
|
enum {
|
||||||
|
kRemoveCmd = 'JDrm',
|
||||||
|
kPortCmd = 'JDpt'
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -646,7 +646,7 @@
|
||||||
<DataExecutionPrevention>
|
<DataExecutionPrevention>
|
||||||
</DataExecutionPrevention>
|
</DataExecutionPrevention>
|
||||||
<TargetMachine>MachineX64</TargetMachine>
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
<LinkTimeCodeGeneration>PGUpdate</LinkTimeCodeGeneration>
|
<LinkTimeCodeGeneration>PGOptimization</LinkTimeCodeGeneration>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Sanitize|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Sanitize|x64'">
|
||||||
|
|
Loading…
Reference in New Issue