Added dialog showing internal joystick database, with ability to

completely remove (currently unplugged) sticks from it.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@3115 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2014-12-23 00:44:09 +00:00
parent 3b02c309c1
commit 233fd75522
9 changed files with 293 additions and 30 deletions

View File

@ -22,9 +22,15 @@
* Fixed major bug with joysticks, where mapping was being lost on reset,
the app would crash when plugging/unplugging certain sticks, etc.
* Added dialog which shows the joystick database, and the ability to
remove (currently unplugged) joysticks from this database.
* Added preliminary support for 'WD' (Wickstead Design) bankswitching
scheme.
* The minimum supported version for the OSX port is now OSX 10.7.
Because of this, the 32-bit version is also discontinued, as 10.7
is 64-bit Intel only.
supports 64-bit Intel only apps.
* The debugger 'reset' command now does a complete system reset,
instead of simply setting the PC to the reset vector address.

View File

@ -1251,6 +1251,22 @@ void EventHandler::setComboMap()
saveComboMapping();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VariantList EventHandler::joystickDatabase() const
{
VariantList db;
for(const auto& i: myJoyHandler->database())
VarList::push_back(db, i.first, i.second.joy ? i.second.joy->ID : -1);
return db;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::removeJoystickFromDatabase(const string& name)
{
myJoyHandler->remove(name);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool EventHandler::addKeyMapping(Event::Type event, EventMode mode, StellaKey key)
{

View File

@ -235,7 +235,7 @@ class EventHandler
string keyAtIndex(int idx, EventMode mode) const;
/**
Bind a key to an event/action and regenerate the mapping array(s)
Bind a key to an event/action and regenerate the mapping array(s).
@param event The event we are remapping
@param mode The mode where this event is active
@ -245,7 +245,7 @@ class EventHandler
/**
Bind a joystick axis direction to an event/action and regenerate
the mapping array(s)
the mapping array(s).
@param event The event we are remapping
@param mode The mode where this event is active
@ -262,7 +262,7 @@ class EventHandler
/**
Bind a joystick button to an event/action and regenerate the
mapping array(s)
mapping array(s).
@param event The event we are remapping
@param mode The mode where this event is active
@ -277,7 +277,7 @@ class EventHandler
/**
Bind a joystick hat direction to an event/action and regenerate
the mapping array(s)
the mapping array(s).
@param event The event we are remapping
@param mode The mode where this event is active
@ -293,7 +293,7 @@ class EventHandler
bool updateMenus = true);
/**
Erase the specified mapping
Erase the specified mapping.
@param event The event for which we erase all mappings
@param mode The mode where this event is active
@ -301,7 +301,7 @@ class EventHandler
void eraseMapping(Event::Type event, EventMode mode);
/**
Resets the event mappings to default values
Resets the event mappings to default values.
@param event The event which to (re)set (Event::NoType resets all)
@param mode The mode for which the defaults are set
@ -315,12 +315,24 @@ class EventHandler
/**
Joystick emulates 'impossible' directions (ie, left & right
at the same time)
at the same time).
@param allow Whether or not to allow impossible directions
*/
void allowAllDirections(bool allow) { myAllowAllDirectionsFlag = allow; }
/**
Return a list of all joysticks currently in the internal database
(first part of variant) and its internal ID (second part of variant).
*/
VariantList joystickDatabase() const;
/**
Remove the joystick identified by 'name' from the joystick database,
only if it is not currently active.
*/
void removeJoystickFromDatabase(const string& name);
protected:
// Global OSystem object
OSystem& myOSystem;
@ -424,27 +436,7 @@ class EventHandler
class JoystickHandler
{
using StickList = map<int, StellaJoystick*>;
public:
JoystickHandler(OSystem& system);
~JoystickHandler();
bool add(StellaJoystick* stick);
bool remove(int id);
void mapStelladaptors(const string& saport);
void setDefaultMapping(Event::Type type, EventMode mode);
void eraseMapping(Event::Type event, EventMode mode);
void saveMapping();
const StellaJoystick* joy(int id) const {
const auto& i = mySticks.find(id);
return i != mySticks.cend() ? i->second : nullptr;
}
const StickList& sticks() const { return mySticks; }
private:
OSystem& myOSystem;
struct StickInfo
{
StickInfo(const string& map = EmptyString, StellaJoystick* stick = nullptr)
@ -458,8 +450,34 @@ class EventHandler
return os;
}
};
public:
using StickDatabase = map<string,StickInfo>;
using StickList = map<int, StellaJoystick*>;
JoystickHandler(OSystem& system);
~JoystickHandler();
bool add(StellaJoystick* stick);
bool remove(int id);
bool remove(const string& name);
void mapStelladaptors(const string& saport);
void setDefaultMapping(Event::Type type, EventMode mode);
void eraseMapping(Event::Type event, EventMode mode);
void saveMapping();
const StellaJoystick* joy(int id) const {
const auto& i = mySticks.find(id);
return i != mySticks.cend() ? i->second : nullptr;
}
const StickDatabase& database() const { return myDatabase; }
const StickList& sticks() const { return mySticks; }
private:
OSystem& myOSystem;
// Contains all joysticks that Stella knows about, indexed by name
map<string,StickInfo> myDatabase;
StickDatabase myDatabase;
// Contains only joysticks that are currently available, indexed by id
StickList mySticks;

View File

@ -393,6 +393,18 @@ bool EventHandler::JoystickHandler::remove(int id)
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool EventHandler::JoystickHandler::remove(const string& name)
{
auto it = myDatabase.find(name);
if(it != myDatabase.end() && it->second.joy == nullptr)
{
myDatabase.erase(it);
return true;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::JoystickHandler::mapStelladaptors(const string& saport)
{

View File

@ -202,6 +202,12 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
myHideCursor->clearFlags(WIDGET_ENABLED);
#endif
// Show joystick database
xpos += 20; ypos += lineHeight + 8;
myJoyDlgButton = new ButtonWidget(myTab, font, xpos, ypos,
font.getStringWidth("Show Joystick Database") + 20, font.getLineHeight() + 4,
"Show Joystick Database", kDBButtonPressed);
// Add items for virtual device ports
addToFocusList(wid, myTab, tabID);
}
@ -412,6 +418,13 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd,
myMPaddleLabel->setValue(myMPaddleSpeed->getValue());
break;
case kDBButtonPressed:
if(!myJoyDialog)
myJoyDialog = make_ptr<JoystickDialog>
(this, instance().frameBuffer().font(), _w-60, _h-60);
myJoyDialog->show();
break;
default:
Dialog::handleCommand(sender, cmd, data, 0);
}

View File

@ -31,6 +31,7 @@ class SliderWidget;
class StaticTextWidget;
#include "Dialog.hxx"
#include "JoystickDialog.hxx"
#include "bspf.hxx"
class InputDialog : public Dialog
@ -58,7 +59,8 @@ class InputDialog : public Dialog
enum {
kDeadzoneChanged = 'DZch',
kDPSpeedChanged = 'PDch',
kMPSpeedChanged = 'PMch'
kMPSpeedChanged = 'PMch',
kDBButtonPressed = 'DBbp'
};
TabWidget* myTab;
@ -80,6 +82,11 @@ class InputDialog : public Dialog
CheckboxWidget* myAllowAll4;
CheckboxWidget* myGrabMouse;
CheckboxWidget* myHideCursor;
ButtonWidget* myJoyDlgButton;
// Show the list of joysticks that the eventhandler knows about
unique_ptr<JoystickDialog> myJoyDialog;
};
#endif

128
src/gui/JoystickDialog.cxx Normal file
View File

@ -0,0 +1,128 @@
//============================================================================
//
// 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-2014 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.
//
// $Id$
//============================================================================
#include "OSystem.hxx"
#include "Widget.hxx"
#include "EditTextWidget.hxx"
#include "StringListWidget.hxx"
#include "Variant.hxx"
#include "JoystickDialog.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font,
int max_w, int max_h)
: Dialog(boss->instance(), boss->parent(), 0, 0, max_w, max_h)
{
int xpos, ypos;
WidgetArray wid;
int buttonWidth = font.getStringWidth("Close") + 20,
buttonHeight = font.getLineHeight() + 4;
// Joystick list
xpos = 10; ypos = 10;
int w = _w - 2 * xpos;
int h = _h - buttonHeight - ypos - 20;
myJoyList = new StringListWidget(this, font, xpos, ypos, w, h);
wid.push_back(myJoyList);
// Joystick ID
ypos = _h - buttonHeight - 10;
StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos,
font.getStringWidth("Joystick ID: "), font.getFontHeight(),
"Joystick ID: ", kTextAlignLeft);
xpos += t->getWidth() + 4;
myJoyText = new EditTextWidget(this, font, xpos, ypos-2,
font.getStringWidth("Unplugged")+8, font.getLineHeight(), "");
myJoyText->setEditable(false);
// Add buttons at bottom
xpos = _w - buttonWidth - 10;
myCloseBtn = new ButtonWidget(this, font, xpos, ypos,
buttonWidth, buttonHeight, "Close", kCloseCmd);
addOKWidget(myCloseBtn); addCancelWidget(myCloseBtn);
buttonWidth = font.getStringWidth("Remove") + 20;
xpos -= buttonWidth + 5;
myRemoveBtn = new ButtonWidget(this, font, xpos, ypos,
buttonWidth, buttonHeight, "Remove", kRemoveCmd);
myRemoveBtn->clearFlags(WIDGET_ENABLED);
// Now we can finally add the widgets to the focus list
wid.push_back(myRemoveBtn);
wid.push_back(myCloseBtn);
addToFocusList(wid);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
JoystickDialog::~JoystickDialog()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JoystickDialog::loadConfig()
{
myJoyIDs.clear();
StringList sticks;
for(const auto& i: instance().eventHandler().joystickDatabase())
{
sticks.push_back(i.first);
myJoyIDs.push_back(i.second.toInt());
}
myJoyList->setList(sticks);
if(sticks.size() > 0)
myJoyList->setSelected(0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
switch(cmd)
{
case kOKCmd:
close();
break;
case kRemoveCmd:
instance().eventHandler().removeJoystickFromDatabase(myJoyList->getSelectedString());
loadConfig();
break;
case ListWidget::kSelectionChangedCmd:
if(myJoyIDs[data] >= 0)
{
myRemoveBtn->setEnabled(false);
ostringstream buf;
buf << "J" << myJoyIDs[data];
myJoyText->setText(buf.str());
}
else
{
myRemoveBtn->setEnabled(true);
myJoyText->setText("Unplugged");
}
break;
default:
Dialog::handleCommand(sender, cmd, data, id);
break;
}
}

View File

@ -0,0 +1,62 @@
//============================================================================
//
// 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-2014 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.
//
// $Id$
//============================================================================
#ifndef JOYSTICK_DIALOG_HXX
#define JOYSTICK_DIALOG_HXX
class GuiObject;
class ButtonWidget;
class EditTextWidgetWidget;
class StringListWidget;
#include "Dialog.hxx"
#include "Command.hxx"
#include "DialogContainer.hxx"
/**
* Show a listing of joysticks currently stored in the eventhandler database,
* and allow to remove those that aren't currently being used.
*/
class JoystickDialog : public Dialog
{
public:
JoystickDialog(GuiObject* boss, const GUI::Font& font,
int max_w, int max_h);
virtual ~JoystickDialog();
/** Place the dialog onscreen and center it */
void show() { open(); }
private:
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
private:
StringListWidget* myJoyList;
EditTextWidget* myJoyText;
ButtonWidget* myRemoveBtn;
ButtonWidget* myCloseBtn;
IntArray myJoyIDs;
enum { kRemoveCmd = 'JDrm' };
};
#endif

View File

@ -23,6 +23,7 @@ MODULE_OBJS := \
src/gui/HelpDialog.o \
src/gui/InputDialog.o \
src/gui/InputTextDialog.o \
src/gui/JoystickDialog.o \
src/gui/Launcher.o \
src/gui/LauncherDialog.o \
src/gui/LauncherFilterDialog.o \