Added 'mcontrol' commandline argument, which allows to map mouse axes

separately to different paddles.

Updated documentation for impending 3.5 release.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2296 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2011-12-26 21:40:28 +00:00
parent b6cab4e626
commit aeb8d27746
33 changed files with 502 additions and 212 deletions

View File

@ -9,7 +9,7 @@
SSSS ttt eeeee llll llll aaaaa SSSS ttt eeeee llll llll aaaaa
=========================================================================== ===========================================================================
Release 3.4.1 for Linux, MacOSX and Windows Release 3.5 for Linux, MacOSX and Windows
=========================================================================== ===========================================================================
The Atari 2600 Video Computer System (VCS), introduced in 1977, was the The Atari 2600 Video Computer System (VCS), introduced in 1977, was the
@ -21,31 +21,31 @@ all of your favourite Atari 2600 games again! Stella was originally
developed for Linux by Bradford W. Mott, however, it has been ported to a developed for Linux by Bradford W. Mott, however, it has been ported to a
number of other platforms and is currently maintained by Stephen Anthony. number of other platforms and is currently maintained by Stephen Anthony.
This is the 3.4.1 release of Stella for Linux, Mac OSX and Windows. The This is the 3.5 release of Stella for Linux, Mac OSX and Windows. The
distributions currently available are: distributions currently available are:
* Binaries for Windows XP/Vista/7 : * Binaries for Windows XP/Vista/7 :
Stella-3.4.1-win32.exe (32-bit EXE installer) Stella-3.5-win32.exe (32-bit EXE installer)
Stella-3.4.1-x64.exe (64-bit EXE installer) Stella-3.5-x64.exe (64-bit EXE installer)
Stella-3.4.1-windows.zip (32/64 bit versions) Stella-3.5-windows.zip (32/64 bit versions)
* Binaries for Windows 98/2000 : * Binaries for Windows 98/2000 :
Stella-3.4.1_98_2k-windows.zip (32-bit for Windows 98/2000) Stella-3.5_98_2k-windows.zip (32-bit for Windows 98/2000)
* Binary distribution for MacOSX 32-bit & 64-bit : * Binary distribution for MacOSX 32-bit & 64-bit :
Stella-3.4.1-macosx.dmg (32-bit Universal Binary) Stella-3.5-macosx.dmg (32-bit Universal Binary)
Stella-3.4.1_intel_10.6-macosx.dmg (32/64-bit Intel/Snow-Leopard only) Stella-3.5_intel_10.6-macosx.dmg (32/64-bit Intel/Snow-Leopard only)
* Binary distribution in 32-bit & 64-bit Ubuntu DEB format : * Binary distribution in 32-bit & 64-bit Ubuntu DEB format :
stella_3.4.1-1_i386.deb stella_3.5-1_i386.deb
stella_3.4.1-1_amd64.deb stella_3.5-1_amd64.deb
* Binary distribution in 32-bit & 64-bit RPM format : * Binary distribution in 32-bit & 64-bit RPM format :
stella-3.4.1-2.i386.rpm stella-3.5-2.i386.rpm
stella-3.4.1-2.x86_64.rpm stella-3.5-2.x86_64.rpm
* Source code distribution for all platforms : * Source code distribution for all platforms :
stella-3.4.1-src.tar.gz stella-3.5-src.tar.gz
PLEASE DO NOT WRITE ASKING FOR ROM IMAGES TO USE WITH STELLA! ALL SUCH PLEASE DO NOT WRITE ASKING FOR ROM IMAGES TO USE WITH STELLA! ALL SUCH
REQUESTS WILL BE IGNORED! REQUESTS WILL BE IGNORED!

View File

@ -12,7 +12,7 @@
Release History Release History
=========================================================================== ===========================================================================
3.4.1 to 3.5: (December xx, 2011) 3.4.1 to 3.5: (December 31, 2011)
* Added several improvements to the joystick management code. Joystick * Added several improvements to the joystick management code. Joystick
event mapping is now saved per device, meaning that if you map events event mapping is now saved per device, meaning that if you map events
@ -27,6 +27,11 @@
mapping for joystick 0 would inadvertantly change settings for mapping for joystick 0 would inadvertantly change settings for
joystick 1, and could potentially lead to a program crash. joystick 1, and could potentially lead to a program crash.
* Added 'mcontrol' commandline argument, which can specify to use each
mouse axis as a separate paddle. The old (and default) behaviour can
be activated by setting this argument to 'auto'. Related to this,
removed redundant 'usemouse' argument.
* Huge restructuring of the OpenGL code, making it compatible with * Huge restructuring of the OpenGL code, making it compatible with
OpenGL 2.x+ features (such as vertex buffer objects), while at the OpenGL 2.x+ features (such as vertex buffer objects), while at the
same time keeping compatibility with OpenGL 1.5 / OpenGL ES. same time keeping compatibility with OpenGL 1.5 / OpenGL ES.

View File

@ -171,11 +171,7 @@ install: all
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications" $(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications"
$(INSTALL) -c -m 644 "$(srcdir)/src/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications" $(INSTALL) -c -m 644 "$(srcdir)/src/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons" $(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons"
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/mini"
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/large"
$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons" $(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons"
$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons/mini"
$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons/large"
install-strip: install install-strip: install
$(STRIP) stella$(EXEEXT) $(STRIP) stella$(EXEEXT)
@ -185,8 +181,6 @@ uninstall:
rm -rf "$(DESTDIR)$(DOCDIR)/" rm -rf "$(DESTDIR)$(DOCDIR)/"
rm -f "$(DESTDIR)$(DATADIR)/applications/stella.desktop" rm -f "$(DESTDIR)$(DATADIR)/applications/stella.desktop"
rm -f "$(DESTDIR)$(DATADIR)/icons/stella.png" rm -f "$(DESTDIR)$(DATADIR)/icons/stella.png"
rm -f "$(DESTDIR)$(DATADIR)/icons/mini/stella.png"
rm -f "$(DESTDIR)$(DATADIR)/icons/large/stella.png"
# Special rule for M6502.ins, generated from m4 (there's probably a better way to do this ...) # Special rule for M6502.ins, generated from m4 (there's probably a better way to do this ...)
src/emucore/M6502.ins: src/emucore/M6502.m4 src/emucore/M6502.ins: src/emucore/M6502.m4

View File

@ -1,4 +1,4 @@
This is release 3.4.1 of Stella. Stella is a multi-platform Atari 2600 VCS This is release 3.5 of Stella. Stella is a multi-platform Atari 2600 VCS
emulator which allows you to play all of your favourite Atari 2600 games emulator which allows you to play all of your favourite Atari 2600 games
on your PC. You'll find the Stella Users Manual in the docs subdirectory. on your PC. You'll find the Stella Users Manual in the docs subdirectory.
If you'd like to verify that you have the latest release of Stella visit If you'd like to verify that you have the latest release of Stella visit
@ -9,4 +9,4 @@ the Stella Website at:
Enjoy, Enjoy,
The Stella Team The Stella Team
June 11, 2011 December 31, 2011

View File

@ -12,9 +12,7 @@
To Do List To Do List
=========================================================================== ===========================================================================
All Todo items are now available in the Stella tracker on AtariAge: If you would like to contribute to Stella's development then feel free to
contact me by email:
http://www.atariage.com/forums/tracker/project-16-stella-emulator Stephen Anthony (stephena@users.sf.net).
If you would like to contribute to Stella's development then find something
on the list above and email Stephen Anthony (stephena@users.sf.net).

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
stella (3.5-1) stable; urgency=high
* Version 3.5 release
-- Stephen Anthony <stephena@users.sf.net> Sat, 31 Dec 2011 18:38:25 +0200
stella (3.4.1-1) stable; urgency=high stella (3.4.1-1) stable; urgency=high
* Version 3.4.1 release * Version 3.4.1 release

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -1794,13 +1794,15 @@
</tr> </tr>
<tr> <tr>
<td><pre>-usemouse &lt;1|0&gt;</pre></td> <td><pre>-grabmouse &lt;1|0&gt;</pre></td>
<td>Enable using the mouse for various controllers (paddle, driving, etc).</td> <td>Keeps the mouse in the game window in emulation mode.</td>
</tr> </tr>
<tr> <tr>
<td><pre>-grabmouse &lt;1|0&gt;</pre></td> <td><pre>-mcontrol &lt;auto|XY&gt;</pre></td>
<td>Keeps the mouse in the game window in emulation mode.</td> <td>Enable using the mouse axes for various controllers automatically (paddle, driving, etc),
or specifically use each axis for a particular paddle. In the latter case, XY indicates
how to use the X/Y axis (ie, 02 is paddle0/paddle2, etc).</td>
</tr> </tr>
<tr> <tr>
@ -2387,8 +2389,8 @@
<tr><td>Digital paddle sensitivity</td><td>Sensitvity used when emulating a paddle using a digital device</td><td>-dsense</td></tr> <tr><td>Digital paddle sensitivity</td><td>Sensitvity used when emulating a paddle using a digital device</td><td>-dsense</td></tr>
<tr><td>Mouse paddle sensitivity</td><td>Sensitivity used when emulating a paddle using a mouse</td><td>-msense</td></tr> <tr><td>Mouse paddle sensitivity</td><td>Sensitivity used when emulating a paddle using a mouse</td><td>-msense</td></tr>
<tr><td>Allow all 4 ...</td><td>Allow all 4 joystick directions to be pressed simultaneously</td><td>-joyallow4</td></tr> <tr><td>Allow all 4 ...</td><td>Allow all 4 joystick directions to be pressed simultaneously</td><td>-joyallow4</td></tr>
<tr><td>Use mouse as ...</td><td>Use the mouse for various controllers (paddles, driving, etc)</td><td>-usemouse</td></tr>
<tr><td>Grab mouse ...</td><td>Keep mouse in window in emulation mode</td><td>-grabmouse</td></tr> <tr><td>Grab mouse ...</td><td>Keep mouse in window in emulation mode</td><td>-grabmouse</td></tr>
<tr><td>Use mouse as ...</td><td>Mouse axes are either automatically or specifically mapped to certain actions</td><td>-mcontrol</td></tr>
</table> </table>
</td> </td>
</tr> </tr>

View File

@ -122,6 +122,14 @@ template<typename T> inline T BSPF_abs (T x) { return (x>=0) ? x : -x; }
template<typename T> inline T BSPF_min (T a, T b) { return (a<b) ? a : b; } template<typename T> inline T BSPF_min (T a, T b) { return (a<b) ? a : b; }
template<typename T> inline T BSPF_max (T a, T b) { return (a>b) ? a : b; } template<typename T> inline T BSPF_max (T a, T b) { return (a>b) ? a : b; }
// Convert integer to string
inline string BSPF_toString(int num)
{
ostringstream buf;
buf << num;
return buf.str();
}
// Test whether two strings are equal (case insensitive) // Test whether two strings are equal (case insensitive)
inline bool BSPF_equalsIgnoreCase(const string& s1, const string& s2) inline bool BSPF_equalsIgnoreCase(const string& s1, const string& s2)
{ {

View File

@ -22,7 +22,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system) BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::BoosterGrip) : Controller(jack, event, system, Controller::BoosterGrip),
myControlID(-1)
{ {
if(myJack == Left) if(myJack == Left)
{ {
@ -97,8 +98,7 @@ void BoosterGrip::update()
// Mouse motion and button events // Mouse motion and button events
// Since there are 4 possible controller numbers, we use 0 & 2 // Since there are 4 possible controller numbers, we use 0 & 2
// for the left jack, and 1 & 3 for the right jack // for the left jack, and 1 & 3 for the right jack
if((myJack == Left && !(ourControlNum & 0x1)) || if(myControlID > -1)
(myJack == Right && ourControlNum & 0x1))
{ {
// The following code was taken from z26 // The following code was taken from z26
#define MJ_Threshold 2 #define MJ_Threshold 2
@ -127,3 +127,18 @@ void BoosterGrip::update()
myDigitalPinState[Six] = false; myDigitalPinState[Six] = false;
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BoosterGrip::setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID)
{
// In 'automatic' mode, both axes on the mouse map to a single normal booster
if(xaxis == Controller::Automatic || yaxis == Controller::Automatic)
{
myControlID = ((myJack == Left && (ctrlID == 0 || ctrlID == 1)) ||
(myJack == Right && (ctrlID == 2 || ctrlID == 3))
) ? ctrlID & 0x01 : -1;
}
else // Otherwise, boosters are not used in 'non-auto' mode
myControlID = -1;
}

View File

@ -55,12 +55,34 @@ class BoosterGrip : public Controller
*/ */
void update(); void update();
/**
Determines how this controller will treat values received from the
X and Y axis of the mouse. Since not all controllers use the mouse,
it's up to the specific class to decide how to use this data.
If either of the axis is set to 'Automatic', then we automatically
use this number for the control type as follows:
0 - paddle 0, joystick 0 (and controllers similar to a joystick)
1 - paddle 1, joystick 1 (and controllers similar to a joystick)
2 - paddle 2, joystick 0 (and controllers similar to a joystick)
3 - paddle 3, joystick 1 (and controllers similar to a joystick)
@param xaxis How the controller should use x-axis data
@param yaxis How the controller should use y-axis data
@param ctrlID The controller ID to use axis 'auto' mode
*/
void setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID = -1);
private: private:
// Pre-compute the events we care about based on given port // Pre-compute the events we care about based on given port
// This will eliminate test for left or right port in update() // This will eliminate test for left or right port in update()
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent, Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent,
myFireEvent, myBoosterEvent, myTriggerEvent, myFireEvent, myBoosterEvent, myTriggerEvent,
myXAxisValue, myYAxisValue; myXAxisValue, myYAxisValue;
// Controller to emulate in mouse axis 'automatic' mode
int myControlID;
}; };
#endif #endif

View File

@ -618,8 +618,6 @@ void Console::setControllers(const string& rommd5)
// Also check if we should swap the paddles plugged into a jack // Also check if we should swap the paddles plugged into a jack
bool swapPaddles = myProperties.get(Controller_SwapPaddles) == "YES"; bool swapPaddles = myProperties.get(Controller_SwapPaddles) == "YES";
// Set default controller for mouse
Controller::setMouseIsController(0);
// Construct left controller // Construct left controller
if(left == "BOOSTERGRIP") if(left == "BOOSTERGRIP")
@ -636,7 +634,6 @@ void Console::setControllers(const string& rommd5)
} }
else if(BSPF_startsWithIgnoreCase(left, "PADDLES")) else if(BSPF_startsWithIgnoreCase(left, "PADDLES"))
{ {
Controller::setMouseIsController(swapPaddles ? 1 : 0);
bool swapAxis = false, swapDir = false; bool swapAxis = false, swapDir = false;
if(left == "PADDLES_IAXIS") if(left == "PADDLES_IAXIS")
swapAxis = true; swapAxis = true;

View File

@ -182,23 +182,12 @@ string Controller::about() const
return name() + " in " + (myJack == Left ? "left port" : "right port"); return name() + " in " + (myJack == Left ? "left port" : "right port");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Controller::setMouseIsController(int number)
{
ourControlNum = number;
if(ourControlNum < 0) ourControlNum = 0;
else if (ourControlNum > 3) ourControlNum = 3;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Int32 Controller::maximumResistance = 0x7FFFFFFF; const Int32 Controller::maximumResistance = 0x7FFFFFFF;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Int32 Controller::minimumResistance = 0x00000000; const Int32 Controller::minimumResistance = 0x00000000;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 Controller::ourControlNum = 0;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::Controller(const Controller& c) Controller::Controller(const Controller& c)
: myJack(c.myJack), : myJack(c.myJack),

View File

@ -71,10 +71,17 @@ class Controller : public Serializable
/** /**
Enumeration of the controller jacks Enumeration of the controller jacks
*/ */
enum Jack enum Jack { Left, Right };
{
Left, Right /**
}; Enumeration of the digital pins of a controller port
*/
enum DigitalPin { One, Two, Three, Four, Six };
/**
Enumeration of the analog pins of a controller port
*/
enum AnalogPin { Five, Nine };
/** /**
Enumeration of the controller types Enumeration of the controller types
@ -86,6 +93,15 @@ class Controller : public Serializable
KidVid, Genesis KidVid, Genesis
}; };
/**
Enumeration of mouse axis control types
*/
enum MouseAxisControl
{
Paddle0 = 0, Paddle1, Paddle2, Paddle3,
Automatic, NoControl
};
public: public:
/** /**
Create a new controller plugged into the specified jack Create a new controller plugged into the specified jack
@ -108,24 +124,6 @@ class Controller : public Serializable
*/ */
const Type type() const; const Type type() const;
public:
/**
Enumeration of the digital pins of a controller port
*/
enum DigitalPin
{
One, Two, Three, Four, Six
};
/**
Enumeration of the analog pins of a controller port
*/
enum AnalogPin
{
Five, Nine
};
public:
/** /**
Read the value of the specified digital pin for this controller. Read the value of the specified digital pin for this controller.
@ -162,10 +160,29 @@ class Controller : public Serializable
/** /**
Notification method invoked by the system right before the Notification method invoked by the system right before the
system resets its cycle counter to zero. It may be necessary system resets its cycle counter to zero. It may be necessary
to override this method for devices that remember cycle counts. to override this method for controllers that remember cycle counts.
*/ */
virtual void systemCyclesReset() { }; virtual void systemCyclesReset() { };
/**
Determines how this controller will treat values received from the
X and Y axis of the mouse. Since not all controllers use the mouse,
it's up to the specific class to decide how to use this data.
If either of the axis is set to 'Automatic', then we automatically
use this number for the control type as follows:
0 - paddle 0, joystick 0 (and controllers similar to a joystick)
1 - paddle 1, joystick 1 (and controllers similar to a joystick)
2 - paddle 2, joystick 0 (and controllers similar to a joystick)
3 - paddle 3, joystick 1 (and controllers similar to a joystick)
@param xaxis How the controller should use x-axis data
@param yaxis How the controller should use y-axis data
@param ctrlID The controller ID to use axis 'auto' mode
*/
virtual void setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID = -1) { };
/** /**
Returns the name of this controller. Returns the name of this controller.
*/ */
@ -192,17 +209,6 @@ class Controller : public Serializable
*/ */
bool load(Serializer& in); bool load(Serializer& in);
/**
Sets the mouse to emulate controller number 'X'. Note that this
can accept values 0 to 3, since there can be up to four possible
controllers (when using paddles). In all other cases when only
two controllers are present, it's up to the specific class to
decide how to use this data.
@param number The controller number (0, 1, 2, 3)
*/
static void setMouseIsController(int number);
public: public:
/// Constant which represents maximum resistance for analog pins /// Constant which represents maximum resistance for analog pins
static const Int32 maximumResistance; static const Int32 maximumResistance;
@ -232,9 +238,6 @@ class Controller : public Serializable
/// The analog value on each analog pin /// The analog value on each analog pin
Int32 myAnalogPinValue[2]; Int32 myAnalogPinValue[2];
/// The controller number
static Int32 ourControlNum;
protected: protected:
// Copy constructor isn't supported by controllers so make it private // Copy constructor isn't supported by controllers so make it private
Controller(const Controller&); Controller(const Controller&);

View File

@ -25,7 +25,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Driving::Driving(Jack jack, const Event& event, const System& system) Driving::Driving(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Driving), : Controller(jack, event, system, Controller::Driving),
myCounter(0) myCounter(0),
myControlID(-1)
{ {
if(myJack == Left) if(myJack == Left)
{ {
@ -72,8 +73,7 @@ void Driving::update()
// Mouse motion and button events // Mouse motion and button events
// Since there are 4 possible controller numbers, we use 0 & 2 // Since there are 4 possible controller numbers, we use 0 & 2
// for the left jack, and 1 & 3 for the right jack // for the left jack, and 1 & 3 for the right jack
if((myJack == Left && !(ourControlNum & 0x1)) || if(myControlID > -1)
(myJack == Right && ourControlNum & 0x1))
{ {
int m_axis = myEvent.get(Event::MouseAxisXValue); int m_axis = myEvent.get(Event::MouseAxisXValue);
if(m_axis < -2) myCounter--; if(m_axis < -2) myCounter--;
@ -112,3 +112,18 @@ void Driving::update()
myDigitalPinState[One] = (gray & 0x1) != 0; myDigitalPinState[One] = (gray & 0x1) != 0;
myDigitalPinState[Two] = (gray & 0x2) != 0; myDigitalPinState[Two] = (gray & 0x2) != 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Driving::setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID)
{
// In 'automatic' mode, both axes on the mouse map to a single normal joystick
if(xaxis == Controller::Automatic || yaxis == Controller::Automatic)
{
myControlID = ((myJack == Left && (ctrlID == 0 || ctrlID == 1)) ||
(myJack == Right && (ctrlID == 2 || ctrlID == 3))
) ? ctrlID & 0x01 : -1;
}
else // Otherwise, joysticks are not used in 'non-auto' mode
myControlID = -1;
}

View File

@ -55,6 +55,25 @@ class Driving : public Controller
*/ */
void update(); void update();
/**
Determines how this controller will treat values received from the
X and Y axis of the mouse. Since not all controllers use the mouse,
it's up to the specific class to decide how to use this data.
If either of the axis is set to 'Automatic', then we automatically
use this number for the control type as follows:
0 - paddle 0, joystick 0 (and controllers similar to a joystick)
1 - paddle 1, joystick 1 (and controllers similar to a joystick)
2 - paddle 2, joystick 0 (and controllers similar to a joystick)
3 - paddle 3, joystick 1 (and controllers similar to a joystick)
@param xaxis How the controller should use x-axis data
@param yaxis How the controller should use y-axis data
@param ctrlID The controller ID to use axis 'auto' mode
*/
void setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID = -1);
private: private:
// Counter to iterate through the gray codes // Counter to iterate through the gray codes
uInt32 myCounter; uInt32 myCounter;
@ -70,6 +89,9 @@ class Driving : public Controller
// This will eliminate test for left or right port in update() // This will eliminate test for left or right port in update()
Event::Type myCWEvent, myCCWEvent, myFireEvent, Event::Type myCWEvent, myCCWEvent, myFireEvent,
myXAxisValue, myYAxisValue, myAxisMouseMotion; myXAxisValue, myYAxisValue, myAxisMouseMotion;
// Controller to emulate in mouse axis 'automatic' mode
int myControlID;
}; };
#endif #endif

View File

@ -125,7 +125,6 @@ void EventHandler::initialize()
Joystick::setDeadZone(myOSystem->settings().getInt("joydeadzone")); Joystick::setDeadZone(myOSystem->settings().getInt("joydeadzone"));
Paddles::setDigitalSensitivity(myOSystem->settings().getInt("dsense")); Paddles::setDigitalSensitivity(myOSystem->settings().getInt("dsense"));
Paddles::setMouseSensitivity(myOSystem->settings().getInt("msense")); Paddles::setMouseSensitivity(myOSystem->settings().getInt("msense"));
setMouseControllerMode(myOSystem->settings().getBool("usemouse") ? 0 : -1, false);
// Set quick select delay when typing characters in listwidgets // Set quick select delay when typing characters in listwidgets
ListWidget::setQuickSelectDelay(myOSystem->settings().getInt("listdelay")); ListWidget::setQuickSelectDelay(myOSystem->settings().getInt("listdelay"));
@ -504,20 +503,20 @@ void EventHandler::poll(uInt64 time)
{ {
switch(int(key)) switch(int(key))
{ {
case SDLK_0: // Ctrl-0 sets the mouse to controller 0 case SDLK_0: // Ctrl-0 sets the mouse to paddle 0
setMouseControllerMode(0, true); setMouseAsPaddle(0, "Mouse is paddle 0");
break; break;
case SDLK_1: // Ctrl-1 sets the mouse to controller 1 case SDLK_1: // Ctrl-1 sets the mouse to paddle 1
setMouseControllerMode(1, true); setMouseAsPaddle(1, "Mouse is paddle 1");
break; break;
case SDLK_2: // Ctrl-2 sets the mouse to controller 2 case SDLK_2: // Ctrl-2 sets the mouse to paddle 2
setMouseControllerMode(2, true); setMouseAsPaddle(2, "Mouse is paddle 2");
break; break;
case SDLK_3: // Ctrl-3 sets the mouse to controller 3 case SDLK_3: // Ctrl-3 sets the mouse to paddle 3
setMouseControllerMode(3, true); setMouseAsPaddle(3, "Mouse is paddle 3");
break; break;
case SDLK_f: // Ctrl-f toggles NTSC/PAL mode case SDLK_f: // Ctrl-f toggles NTSC/PAL mode
@ -606,8 +605,6 @@ void EventHandler::poll(uInt64 time)
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
// Determine which mode we're in, then send the event to the appropriate place // Determine which mode we're in, then send the event to the appropriate place
if(myState == S_EMULATE) if(myState == S_EMULATE)
{
if(myMouseEnabled)
{ {
if(!mySkipMouseMotion) if(!mySkipMouseMotion)
{ {
@ -616,7 +613,6 @@ void EventHandler::poll(uInt64 time)
} }
mySkipMouseMotion = false; mySkipMouseMotion = false;
} }
}
else if(myOverlay) else if(myOverlay)
myOverlay->handleMouseMotionEvent(event.motion.x, event.motion.y, 0); myOverlay->handleMouseMotionEvent(event.motion.x, event.motion.y, 0);
@ -630,7 +626,6 @@ void EventHandler::poll(uInt64 time)
// Determine which mode we're in, then send the event to the appropriate place // Determine which mode we're in, then send the event to the appropriate place
if(myState == S_EMULATE) if(myState == S_EMULATE)
{ {
if(myMouseEnabled)
myEvent->set(Event::MouseButtonValue, state); myEvent->set(Event::MouseButtonValue, state);
} }
else if(myOverlay) else if(myOverlay)
@ -1924,21 +1919,52 @@ void EventHandler::takeSnapshot(uInt32 number)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setMouseControllerMode(int num, bool showmessage) void EventHandler::setMouseControllerMode(const string& mode,
const string& message)
{ {
if(num >= 0 && num <= 3) if(!&myOSystem->console())
return;
Controller& lc = myOSystem->console().controller(Controller::Left);
Controller& rc = myOSystem->console().controller(Controller::Right);
if(mode == "auto")
{ {
myMouseEnabled = true; bool swap = myOSystem->console().properties().get(Controller_SwapPaddles) == "YES";
Controller::setMouseIsController(num); lc.setMouseControl(Controller::Automatic, Controller::Automatic, swap ? 1 : 0);
if(showmessage) rc.setMouseControl(Controller::Automatic, Controller::Automatic, swap ? 1 : 0);
{
ostringstream buf;
buf << "Mouse is controller " << num;
myOSystem->frameBuffer().showMessage(buf.str());
}
} }
else else
myMouseEnabled = false; {
Controller::MouseAxisControl xaxis = (Controller::MouseAxisControl)
((int)mode[0] - '0');
Controller::MouseAxisControl yaxis = (Controller::MouseAxisControl)
((int)mode[1] - '0');
lc.setMouseControl(xaxis, yaxis);
rc.setMouseControl(xaxis, yaxis);
}
if(message != "")
myOSystem->frameBuffer().showMessage(message);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setMouseAsPaddle(int paddle, const string& message)
{
if(myOSystem->settings().getString("mcontrol") == "auto")
{
myOSystem->console().controller(Controller::Left).setMouseControl(
Controller::Automatic, Controller::Automatic, paddle);
myOSystem->console().controller(Controller::Right).setMouseControl(
Controller::Automatic, Controller::Automatic, paddle);
myOSystem->frameBuffer().showMessage(message);
}
else
{
myOSystem->frameBuffer().showMessage(
"Mouse axis mode not auto, paddle not changed");
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -151,12 +151,13 @@ class EventHandler
void quit() { handleEvent(Event::Quit, 1); } void quit() { handleEvent(Event::Quit, 1); }
/** /**
Sets the mouse to act as controller 'num' Sets the mouse axis to act as controller 'mode', where the mode is
defined from the Controller::MouseAxisControl enum
@param num The controller which the mouse should emulate @param mode The controller which the mouse axes should emulate
@param showmessage Print a message to the framebuffer @param message Print the (non-empty) message to the framebuffer
*/ */
void setMouseControllerMode(int num, bool showmessage = false); void setMouseControllerMode(const string& mode, const string& message = "");
/** /**
Set the number of seconds between taking a snapshot in Set the number of seconds between taking a snapshot in
@ -338,6 +339,7 @@ class EventHandler
void saveKeyMapping(); void saveKeyMapping();
void saveJoyMapping(); void saveJoyMapping();
void saveComboMapping(); void saveComboMapping();
void setMouseAsPaddle(int paddle, const string& message);
/** /**
Tests if a given event should use continuous/analog values. Tests if a given event should use continuous/analog values.
@ -387,9 +389,6 @@ class EventHandler
// Indicates the current state of the system (ie, which mode is current) // Indicates the current state of the system (ie, which mode is current)
State myState; State myState;
// Indicates whether the mouse is enabled for game controller actions
bool myMouseEnabled;
// Indicates whether the joystick emulates 'impossible' directions // Indicates whether the joystick emulates 'impossible' directions
bool myAllowAllDirectionsFlag; bool myAllowAllDirectionsFlag;

View File

@ -22,7 +22,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Joystick::Joystick(Jack jack, const Event& event, const System& system) Joystick::Joystick(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Joystick) : Controller(jack, event, system, Controller::Joystick),
myControlID(-1)
{ {
if(myJack == Left) if(myJack == Left)
{ {
@ -89,8 +90,7 @@ void Joystick::update()
// Mouse motion and button events // Mouse motion and button events
// Since there are 4 possible controller numbers, we use 0 & 2 // Since there are 4 possible controller numbers, we use 0 & 2
// for the left jack, and 1 & 3 for the right jack // for the left jack, and 1 & 3 for the right jack
if((myJack == Left && !(ourControlNum & 0x1)) || if(myControlID > -1)
(myJack == Right && ourControlNum & 0x1))
{ {
// The following code was taken from z26 // The following code was taken from z26
#define MJ_Threshold 2 #define MJ_Threshold 2
@ -120,6 +120,21 @@ void Joystick::update()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Joystick::setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID)
{
// In 'automatic' mode, both axes on the mouse map to a single normal joystick
if(xaxis == Controller::Automatic || yaxis == Controller::Automatic)
{
myControlID = ((myJack == Left && (ctrlID == 0 || ctrlID == 1)) ||
(myJack == Right && (ctrlID == 2 || ctrlID == 3))
) ? ctrlID & 0x01 : -1;
}
else // Otherwise, joysticks are not used in 'non-auto' mode
myControlID = -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Joystick::setDeadZone(int deadzone) void Joystick::setDeadZone(int deadzone)
{ {

View File

@ -54,6 +54,25 @@ class Joystick : public Controller
*/ */
void update(); void update();
/**
Determines how this controller will treat values received from the
X and Y axis of the mouse. Since not all controllers use the mouse,
it's up to the specific class to decide how to use this data.
If either of the axis is set to 'Automatic', then we automatically
use this number for the control type as follows:
0 - paddle 0, joystick 0 (and controllers similar to a joystick)
1 - paddle 1, joystick 1 (and controllers similar to a joystick)
2 - paddle 2, joystick 0 (and controllers similar to a joystick)
3 - paddle 3, joystick 1 (and controllers similar to a joystick)
@param xaxis How the controller should use x-axis data
@param yaxis How the controller should use y-axis data
@param ctrlID The controller ID to use axis 'auto' mode
*/
void setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID = -1);
/** /**
Sets the deadzone amount for real analog joysticks. Sets the deadzone amount for real analog joysticks.
Technically, this isn't really used by the Joystick class at all, Technically, this isn't really used by the Joystick class at all,
@ -68,6 +87,9 @@ class Joystick : public Controller
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent, Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent,
myXAxisValue, myYAxisValue, myFireEvent; myXAxisValue, myYAxisValue, myFireEvent;
// Controller to emulate in mouse axis 'automatic' mode
int myControlID;
static int _DEAD_ZONE; static int _DEAD_ZONE;
}; };

View File

@ -521,6 +521,7 @@ bool OSystem::createConsole(const string& romfile, const string& md5sum)
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
myConsole->initializeAudio(); myConsole->initializeAudio();
myEventHandler->reset(EventHandler::S_EMULATE); myEventHandler->reset(EventHandler::S_EMULATE);
myEventHandler->setMouseControllerMode(mySettings->getString("mcontrol"));
if(createFrameBuffer() != kSuccess) // Takes care of initializeVideo() if(createFrameBuffer() != kSuccess) // Takes care of initializeVideo()
{ {
logMessage("ERROR: Couldn't create framebuffer for console\n", 0); logMessage("ERROR: Couldn't create framebuffer for console\n", 0);

View File

@ -25,7 +25,10 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Paddles::Paddles(Jack jack, const Event& event, const System& system, Paddles::Paddles(Jack jack, const Event& event, const System& system,
bool swapport, bool swapaxis, bool swapdir) bool swapport, bool swapaxis, bool swapdir)
: Controller(jack, event, system, Controller::Paddles) : Controller(jack, event, system, Controller::Paddles),
myMPaddleID(-1),
myMPaddleIDX(-1),
myMPaddleIDY(-1)
{ {
// The following logic reflects that mapping paddles to different // The following logic reflects that mapping paddles to different
// devices can be extremely complex // devices can be extremely complex
@ -281,18 +284,40 @@ void Paddles::update()
// Mouse motion events give relative movement // Mouse motion events give relative movement
// That is, they're only relevant if they're non-zero // That is, they're only relevant if they're non-zero
if((myJack == Left && ourControlNum <= 1) || if(myMPaddleID > -1)
(myJack == Right && ourControlNum > 1))
{ {
int num = ourControlNum & 0x01; // We're in auto mode, where a single axis is used for one paddle only
myCharge[num] -= myCharge[myMPaddleID] -=
((myEvent.get(myAxisMouseMotion) >> 1) * _MOUSE_SENSITIVITY); ((myEvent.get(myAxisMouseMotion) >> 1) * _MOUSE_SENSITIVITY);
if(myCharge[num] < TRIGMIN) if(myCharge[myMPaddleID] < TRIGMIN)
myCharge[num] = TRIGMIN; myCharge[myMPaddleID] = TRIGMIN;
if(myCharge[num] > TRIGMAX) if(myCharge[myMPaddleID] > TRIGMAX)
myCharge[num] = TRIGMAX; myCharge[myMPaddleID] = TRIGMAX;
if(myEvent.get(Event::MouseButtonValue)) if(myEvent.get(Event::MouseButtonValue))
myDigitalPinState[ourButtonPin[num]] = false; myDigitalPinState[ourButtonPin[myMPaddleID]] = false;
}
else
{
// Test for 'untied' mouse axis mode, where each axis is potentially
// mapped to a separate paddle
if(myMPaddleIDX > -1)
{
myCharge[myMPaddleIDX] -=
((myEvent.get(Event::MouseAxisXValue) >> 1) * _MOUSE_SENSITIVITY);
if(myCharge[myMPaddleIDX] < TRIGMIN)
myCharge[myMPaddleIDX] = TRIGMIN;
if(myCharge[myMPaddleIDX] > TRIGMAX)
myCharge[myMPaddleIDX] = TRIGMAX;
}
if(myMPaddleIDY > -1)
{
myCharge[myMPaddleIDY] -=
((myEvent.get(Event::MouseAxisYValue) >> 1) * _MOUSE_SENSITIVITY);
if(myCharge[myMPaddleIDY] < TRIGMIN)
myCharge[myMPaddleIDY] = TRIGMIN;
if(myCharge[myMPaddleIDY] > TRIGMAX)
myCharge[myMPaddleIDY] = TRIGMAX;
}
} }
// Finally, consider digital input, where movement happens // Finally, consider digital input, where movement happens
@ -350,6 +375,57 @@ void Paddles::update()
myLastCharge[0] = myCharge[0]; myLastCharge[0] = myCharge[0];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Paddles::setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID)
{
// In 'automatic' mode, both axes on the mouse map to a single paddle
// This overrides any other mode
if(xaxis == Controller::Automatic || yaxis == Controller::Automatic)
{
myMPaddleID = ((myJack == Left && (ctrlID == 0 || ctrlID == 1)) ||
(myJack == Right && (ctrlID == 2 || ctrlID == 3))
) ? ctrlID & 0x01 : -1;
myMPaddleIDX = myMPaddleIDY = -1;
}
else
{
// The following is somewhat complex, but we need to pre-process as much
// as possible, so that ::update() can run quickly
myMPaddleID = -1;
if(myJack == Left)
{
switch(xaxis)
{
case Controller::Paddle0: myMPaddleIDX = 0; break;
case Controller::Paddle1: myMPaddleIDX = 1; break;
default: myMPaddleIDX = -1; break;
}
switch(yaxis)
{
case Controller::Paddle0: myMPaddleIDY = 0; break;
case Controller::Paddle1: myMPaddleIDY = 1; break;
default: myMPaddleIDY = -1; break;
}
}
else // myJack == Right
{
switch(xaxis)
{
case Controller::Paddle2: myMPaddleIDX = 0; break;
case Controller::Paddle3: myMPaddleIDX = 1; break;
default: myMPaddleIDX = -1; break;
}
switch(yaxis)
{
case Controller::Paddle2: myMPaddleIDY = 0; break;
case Controller::Paddle3: myMPaddleIDY = 1; break;
default: myMPaddleIDY = -1; break;
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Paddles::setDigitalSensitivity(int sensitivity) void Paddles::setDigitalSensitivity(int sensitivity)
{ {

View File

@ -61,6 +61,25 @@ class Paddles : public Controller
*/ */
void update(); void update();
/**
Determines how this controller will treat values received from the
X and Y axis of the mouse. Since not all controllers use the mouse,
it's up to the specific class to decide how to use this data.
If either of the axis is set to 'Automatic', then we automatically
use this number for the control type as follows:
0 - paddle 0, joystick 0 (and controllers similar to a joystick)
1 - paddle 1, joystick 1 (and controllers similar to a joystick)
2 - paddle 2, joystick 0 (and controllers similar to a joystick)
3 - paddle 3, joystick 1 (and controllers similar to a joystick)
@param xaxis How the controller should use x-axis data
@param yaxis How the controller should use y-axis data
@param ctrlID The controller ID to use axis 'auto' mode
*/
void setMouseControl(
MouseAxisControl xaxis, MouseAxisControl yaxis, int ctrlID = -1);
/** /**
Sets the sensitivity for digital emulation of paddle movement. Sets the sensitivity for digital emulation of paddle movement.
This is only used for *digital* events (ie, buttons or keys, This is only used for *digital* events (ie, buttons or keys,
@ -98,6 +117,10 @@ class Paddles : public Controller
myP0FireEvent1, myP0FireEvent2, myP1FireEvent1, myP1FireEvent2, myP0FireEvent1, myP0FireEvent2, myP1FireEvent1, myP1FireEvent2,
myAxisMouseMotion; myAxisMouseMotion;
// The following are used for the various mouse-axis modes
int myMPaddleID; // paddle to emulate in 'automatic' mode
int myMPaddleIDX, myMPaddleIDY; // paddles to emulate in 'specific axis' mode
bool myKeyRepeat0, myKeyRepeat1; bool myKeyRepeat0, myKeyRepeat1;
int myPaddleRepeat0, myPaddleRepeat1; int myPaddleRepeat0, myPaddleRepeat1;
int myCharge[2], myLastCharge[2]; int myCharge[2], myLastCharge[2];

View File

@ -73,7 +73,7 @@ Settings::Settings(OSystem* osystem)
setInternal("combomap", ""); setInternal("combomap", "");
setInternal("joydeadzone", "13"); setInternal("joydeadzone", "13");
setInternal("joyallow4", "false"); setInternal("joyallow4", "false");
setInternal("usemouse", "true"); setInternal("mcontrol", "auto");
setInternal("dsense", "5"); setInternal("dsense", "5");
setInternal("msense", "7"); setInternal("msense", "7");
setInternal("sa1", "left"); setInternal("sa1", "left");
@ -278,6 +278,16 @@ void Settings::validate()
if(i < 0) setInternal("joydeadzone", "0"); if(i < 0) setInternal("joydeadzone", "0");
else if(i > 29) setInternal("joydeadzone", "29"); else if(i > 29) setInternal("joydeadzone", "29");
s = getString("mcontrol");
if(s != "auto")
{
if(s.length() != 2 || s[0] < '0' || s[0] > '9' || s[1] < '0' || s[1] > '9')
setInternal("mcontrol", "auto");
}
if(i < 1) setInternal("dsense", "1");
else if(i > 10) setInternal("dsense", "10");
i = getInt("dsense"); i = getInt("dsense");
if(i < 1) setInternal("dsense", "1"); if(i < 1) setInternal("dsense", "1");
else if(i > 10) setInternal("dsense", "10"); else if(i > 10) setInternal("dsense", "10");
@ -362,7 +372,7 @@ void Settings::usage()
<< " -logtoconsole <1|0> Log output to console/commandline\n" << " -logtoconsole <1|0> Log output to console/commandline\n"
<< " -joydeadzone <number> Sets 'deadzone' area for analog joysticks (0-29)\n" << " -joydeadzone <number> Sets 'deadzone' area for analog joysticks (0-29)\n"
<< " -joyallow4 <1|0> Allow all 4 directions on a joystick to be pressed simultaneously\n" << " -joyallow4 <1|0> Allow all 4 directions on a joystick to be pressed simultaneously\n"
<< " -usemouse <1|0> Use mouse for various controllers (paddle, driving, etc)\n" << " -mcontrol <auto|XY> Use mouse axes as specified paddle controller type (see manual)\n"
<< " -dsense <number> Sensitivity of digital emulated paddle movement (1-10)\n" << " -dsense <number> Sensitivity of digital emulated paddle movement (1-10)\n"
<< " -msense <number> Sensitivity of mouse emulated paddle movement (1-15)\n" << " -msense <number> Sensitivity of mouse emulated paddle movement (1-15)\n"
<< " -sa1 <left|right> Stelladaptor 1 emulates specified joystick port\n" << " -sa1 <left|right> Stelladaptor 1 emulates specified joystick port\n"

View File

@ -50,7 +50,7 @@ InputDialog::InputDialog(OSystem* osystem, DialogContainer* parent,
// Set real dimensions // Set real dimensions
_w = BSPF_min(50 * fontWidth + 10, max_w); _w = BSPF_min(50 * fontWidth + 10, max_w);
_h = BSPF_min(13 * (lineHeight + 4) + 10, max_h); _h = BSPF_min(14 * (lineHeight + 4) + 14, max_h);
// The tab widget // The tab widget
xpos = 2; ypos = vBorder; xpos = 2; ypos = vBorder;
@ -117,24 +117,19 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
// Stelladaptor mappings // Stelladaptor mappings
xpos = 5; ypos = 5; xpos = 5; ypos = 5;
lwidth = font.getStringWidth("Stelladaptor 2 is: "); lwidth = font.getStringWidth("Stelladaptor port order: ");
pwidth = font.getStringWidth("right virtual port"); pwidth = font.getStringWidth("left / right");
items.clear(); items.clear();
items.push_back("left virtual port", "left"); items.push_back("left / right", "leftright");
items.push_back("right virtual port", "right"); items.push_back("right / left", "rightleft");
myLeftPort = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, mySAPort = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items,
"Stelladaptor 1 is: ", lwidth, kLeftChanged); "Stelladaptor port order: ", lwidth);
wid.push_back(myLeftPort); wid.push_back(mySAPort);
ypos += lineHeight + 5;
// ... use items from above
myRightPort = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items,
"Stelladaptor 2 is: ", lwidth, kRightChanged);
wid.push_back(myRightPort);
// Add AtariVox serial port // Add AtariVox serial port
xpos = 5; ypos += 2*lineHeight; ypos += lineHeight + 5;
lwidth = font.getStringWidth("AVox serial port: ");
int fwidth = _w - xpos - lwidth - 20; int fwidth = _w - xpos - lwidth - 20;
new StaticTextWidget(myTab, font, xpos, ypos, lwidth, fontHeight, new StaticTextWidget(myTab, font, xpos, ypos, lwidth, fontHeight,
"AVox serial port: ", kTextAlignLeft); "AVox serial port: ", kTextAlignLeft);
@ -146,7 +141,7 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
pwidth = font.getMaxCharWidth() * 8; pwidth = font.getMaxCharWidth() * 8;
// Add joystick deadzone setting // Add joystick deadzone setting
ypos += lineHeight + 5; ypos += lineHeight + 8;
myDeadzone = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight, myDeadzone = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
"Joystick deadzone size: ", lwidth, kDeadzoneChanged); "Joystick deadzone size: ", lwidth, kDeadzoneChanged);
myDeadzone->setMinValue(0); myDeadzone->setMaxValue(29); myDeadzone->setMinValue(0); myDeadzone->setMaxValue(29);
@ -157,7 +152,7 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
wid.push_back(myDeadzone); wid.push_back(myDeadzone);
// Add paddle speed (digital emulation) // Add paddle speed (digital emulation)
xpos = 5; ypos += lineHeight + 3; xpos = 5; ypos += lineHeight + 4;
myDPaddleSpeed = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight, myDPaddleSpeed = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
"Digital paddle sensitivity: ", "Digital paddle sensitivity: ",
lwidth, kDPSpeedChanged); lwidth, kDPSpeedChanged);
@ -169,7 +164,7 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
wid.push_back(myDPaddleSpeed); wid.push_back(myDPaddleSpeed);
// Add paddle speed (mouse emulation) // Add paddle speed (mouse emulation)
xpos = 5; ypos += lineHeight + 3; xpos = 5; ypos += lineHeight + 4;
myMPaddleSpeed = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight, myMPaddleSpeed = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
"Mouse paddle sensitivity: ", "Mouse paddle sensitivity: ",
lwidth, kMPSpeedChanged); lwidth, kMPSpeedChanged);
@ -181,17 +176,11 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
wid.push_back(myMPaddleSpeed); wid.push_back(myMPaddleSpeed);
// Add 'allow all 4 directions' for joystick // Add 'allow all 4 directions' for joystick
xpos = 10; ypos += 2*lineHeight; xpos = 10; ypos += lineHeight + 8;
myAllowAll4 = new CheckboxWidget(myTab, font, xpos, ypos, myAllowAll4 = new CheckboxWidget(myTab, font, xpos, ypos,
"Allow all 4 directions on joystick"); "Allow all 4 directions on joystick");
wid.push_back(myAllowAll4); wid.push_back(myAllowAll4);
// Add mouse enable/disable
xpos = 10; ypos += lineHeight + 4;
myMouseEnabled = new CheckboxWidget(myTab, font, xpos, ypos,
"Use mouse as a controller");
wid.push_back(myMouseEnabled);
// Grab mouse (in windowed mode) // Grab mouse (in windowed mode)
ypos += lineHeight + 4; ypos += lineHeight + 4;
myGrabMouse = new CheckboxWidget(myTab, font, xpos, ypos, myGrabMouse = new CheckboxWidget(myTab, font, xpos, ypos,
@ -201,6 +190,38 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
myGrabMouse->clearFlags(WIDGET_ENABLED); myGrabMouse->clearFlags(WIDGET_ENABLED);
#endif #endif
// Mouse is controller type
ypos += lineHeight + 8;
lwidth = font.getStringWidth("Use mouse as a controller: ");
pwidth = font.getStringWidth("Specific axis");
items.clear();
items.push_back("Automatic", "auto");
items.push_back("Specific axis", "paddle");
myMouseControl =
new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items,
"Use mouse as a controller: ", lwidth, kMPCtrlChanged);
wid.push_back(myMouseControl);
// Mouse controller specific axis
lwidth = font.getStringWidth("X-Axis is: ");
pwidth = font.getStringWidth("Paddle 3");
items.clear();
items.push_back("not used", BSPF_toString(Controller::NoControl));
items.push_back("Paddle 0", BSPF_toString(Controller::Paddle0));
items.push_back("Paddle 1", BSPF_toString(Controller::Paddle1));
items.push_back("Paddle 2", BSPF_toString(Controller::Paddle2));
items.push_back("Paddle 3", BSPF_toString(Controller::Paddle3));
xpos = 45; ypos += lineHeight + 4;
myMouseX = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items,
"X-Axis is: ", lwidth);
wid.push_back(myMouseX);
ypos += lineHeight + 4;
myMouseY = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items,
"Y-Axis is: ", lwidth);
wid.push_back(myMouseY);
// Add items for virtual device ports // Add items for virtual device ports
addToFocusList(wid, tabID); addToFocusList(wid, tabID);
} }
@ -210,19 +231,13 @@ void InputDialog::loadConfig()
{ {
// Left & right ports // Left & right ports
const string& sa1 = instance().settings().getString("sa1"); const string& sa1 = instance().settings().getString("sa1");
int lport = sa1 == "right" ? 1 : 0; int portorder = sa1 == "right" ? 1 : 0;
myLeftPort->setSelected(lport); mySAPort->setSelected(portorder);
const string& sa2 = instance().settings().getString("sa2");
int rport = sa2 == "right" ? 1 : 0;
myRightPort->setSelected(rport);
// Joystick deadzone // Joystick deadzone
myDeadzone->setValue(instance().settings().getInt("joydeadzone")); myDeadzone->setValue(instance().settings().getInt("joydeadzone"));
myDeadzoneLabel->setValue(Joystick::deadzone()); myDeadzoneLabel->setValue(Joystick::deadzone());
// Mouse/paddle enabled
myMouseEnabled->setState(instance().settings().getBool("usemouse"));
// Grab mouse // Grab mouse
myGrabMouse->setState(instance().settings().getBool("grabmouse")); myGrabMouse->setState(instance().settings().getBool("grabmouse"));
@ -238,6 +253,24 @@ void InputDialog::loadConfig()
// Allow all 4 joystick directions // Allow all 4 joystick directions
myAllowAll4->setState(instance().settings().getBool("joyallow4")); myAllowAll4->setState(instance().settings().getBool("joyallow4"));
// Mouse is controller type
const string& mcontrol = instance().settings().getString("mcontrol");
bool autoAxis = mcontrol == "auto";
if(autoAxis)
{
myMouseControl->setSelected(0);
myMouseX->setSelected(0);
myMouseY->setSelected(0);
}
else
{
myMouseControl->setSelected(1);
myMouseX->setSelected(BSPF_toString(mcontrol[0] - '0'), "");
myMouseY->setSelected(BSPF_toString(mcontrol[1] - '0'), "");
}
myMouseX->setEnabled(!autoAxis);
myMouseY->setEnabled(!autoAxis);
myTab->loadConfig(); myTab->loadConfig();
} }
@ -245,20 +278,17 @@ void InputDialog::loadConfig()
void InputDialog::saveConfig() void InputDialog::saveConfig()
{ {
// Left & right ports // Left & right ports
const string& sa1 = myLeftPort->getSelectedTag(); int sa_order = mySAPort->getSelected();
const string& sa2 = myRightPort->getSelectedTag(); if(sa_order == 0)
instance().eventHandler().mapStelladaptors(sa1, sa2); instance().eventHandler().mapStelladaptors("left", "right");
else
instance().eventHandler().mapStelladaptors("right", "left");
// Joystick deadzone // Joystick deadzone
int deadzone = myDeadzone->getValue(); int deadzone = myDeadzone->getValue();
instance().settings().setInt("joydeadzone", deadzone); instance().settings().setInt("joydeadzone", deadzone);
Joystick::setDeadZone(deadzone); Joystick::setDeadZone(deadzone);
// Mouse/paddle enabled
bool usemouse = myMouseEnabled->getState();
instance().settings().setBool("usemouse", usemouse);
instance().eventHandler().setMouseControllerMode(usemouse ? 0 : -1);
// Grab mouse // Grab mouse
instance().settings().setBool("grabmouse", myGrabMouse->getState()); instance().settings().setBool("grabmouse", myGrabMouse->getState());
instance().frameBuffer().setCursorState(); instance().frameBuffer().setCursorState();
@ -278,6 +308,13 @@ void InputDialog::saveConfig()
bool allowall4 = myAllowAll4->getState(); bool allowall4 = myAllowAll4->getState();
instance().settings().setBool("joyallow4", allowall4); instance().settings().setBool("joyallow4", allowall4);
instance().eventHandler().allowAllDirections(allowall4); instance().eventHandler().allowAllDirections(allowall4);
// Mouse is controller type
string mcontrol = myMouseControl->getSelectedTag();
if(mcontrol != "auto")
mcontrol = myMouseX->getSelectedTag() + myMouseY->getSelectedTag();
instance().settings().setString("mcontrol", mcontrol);
instance().eventHandler().setMouseControllerMode(mcontrol);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -296,16 +333,12 @@ void InputDialog::setDefaults()
case 2: // Virtual devices case 2: // Virtual devices
{ {
// Left & right ports // Left & right ports
myLeftPort->setSelected("left", "left"); mySAPort->setSelected("leftright", "leftright");
myRightPort->setSelected("right", "right");
// Joystick deadzone // Joystick deadzone
myDeadzone->setValue(0); myDeadzone->setValue(0);
myDeadzoneLabel->setValue(3200); myDeadzoneLabel->setValue(3200);
// Mouse/paddle enabled
myMouseEnabled->setState(true);
// Grab mouse // Grab mouse
myGrabMouse->setState(true); myGrabMouse->setState(true);
@ -320,6 +353,13 @@ void InputDialog::setDefaults()
// Allow all 4 joystick directions // Allow all 4 joystick directions
myAllowAll4->setState(false); myAllowAll4->setState(false);
// Mouse is controller type
myMouseControl->setSelected(0);
myMouseX->setSelected(0);
myMouseY->setSelected(0);
myMouseX->setEnabled(false);
myMouseY->setEnabled(false);
break; break;
} }
@ -398,16 +438,6 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd,
setDefaults(); setDefaults();
break; break;
case kLeftChanged:
myRightPort->setSelected(
myLeftPort->getSelected() == 1 ? 0 : 1);
break;
case kRightChanged:
myLeftPort->setSelected(
myRightPort->getSelected() == 1 ? 0 : 1);
break;
case kDeadzoneChanged: case kDeadzoneChanged:
myDeadzoneLabel->setValue(3200 + 1000*myDeadzone->getValue()); myDeadzoneLabel->setValue(3200 + 1000*myDeadzone->getValue());
break; break;
@ -420,6 +450,14 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd,
myMPaddleLabel->setValue(myMPaddleSpeed->getValue()); myMPaddleLabel->setValue(myMPaddleSpeed->getValue());
break; break;
case kMPCtrlChanged:
{
bool state = myMouseControl->getSelectedTag() != "auto";
myMouseX->setEnabled(state);
myMouseY->setEnabled(state);
break;
}
default: default:
Dialog::handleCommand(sender, cmd, data, 0); Dialog::handleCommand(sender, cmd, data, 0);
} }

View File

@ -56,11 +56,10 @@ class InputDialog : public Dialog
private: private:
enum { enum {
kLeftChanged = 'LCch',
kRightChanged = 'RCch',
kDeadzoneChanged = 'DZch', kDeadzoneChanged = 'DZch',
kDPSpeedChanged = 'PDch', kDPSpeedChanged = 'PDch',
kMPSpeedChanged = 'PMch' kMPSpeedChanged = 'PMch',
kMPCtrlChanged = 'PMcl'
}; };
TabWidget* myTab; TabWidget* myTab;
@ -68,8 +67,7 @@ class InputDialog : public Dialog
EventMappingWidget* myEmulEventMapper; EventMappingWidget* myEmulEventMapper;
EventMappingWidget* myMenuEventMapper; EventMappingWidget* myMenuEventMapper;
PopUpWidget* myLeftPort; PopUpWidget* mySAPort;
PopUpWidget* myRightPort;
EditTextWidget* myAVoxPort; EditTextWidget* myAVoxPort;
@ -80,8 +78,10 @@ class InputDialog : public Dialog
StaticTextWidget* myDPaddleLabel; StaticTextWidget* myDPaddleLabel;
StaticTextWidget* myMPaddleLabel; StaticTextWidget* myMPaddleLabel;
CheckboxWidget* myAllowAll4; CheckboxWidget* myAllowAll4;
CheckboxWidget* myMouseEnabled;
CheckboxWidget* myGrabMouse; CheckboxWidget* myGrabMouse;
PopUpWidget* myMouseControl;
PopUpWidget* myMouseX;
PopUpWidget* myMouseY;
}; };
#endif #endif

View File

@ -53,7 +53,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>StLa</string> <string>StLa</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>3.4.1</string> <string>3.5</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>SDLMain.nib</string> <string>SDLMain.nib</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@ -13,7 +13,7 @@ die() {
exit 1 exit 1
} }
VERSION=3.4.1 VERSION=3.5
ARCH=${ARCH-i486} ARCH=${ARCH-i486}
BUILD=1 BUILD=1

View File

@ -1,5 +1,5 @@
%define name stella %define name stella
%define version 3.4.1 %define version 3.5
%define rel 1 %define rel 1
%define enable_gl 1 %define enable_gl 1
@ -108,6 +108,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version}
%_datadir/icons/large/%{name}.png %_datadir/icons/large/%{name}.png
%changelog %changelog
* Sat Dec 31 2011 Stephen Anthony <stephena@users.sf.net> 3.5-1
- Version 3.5 release
* Sat Jun 11 2011 Stephen Anthony <stephena@users.sf.net> 3.4.1-1 * Sat Jun 11 2011 Stephen Anthony <stephena@users.sf.net> 3.4.1-1
- Version 3.4.1 release - Version 3.4.1 release

View File

@ -36,8 +36,8 @@ IDI_ICON ICON "stella.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,4,1,0 FILEVERSION 3,5,0,0
PRODUCTVERSION 3,4,1,0 PRODUCTVERSION 3,5,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -55,12 +55,12 @@ BEGIN
VALUE "Comments", "The multi-platform Atari 2600 emulator. Stella is released under the GPLv2." VALUE "Comments", "The multi-platform Atari 2600 emulator. Stella is released under the GPLv2."
VALUE "CompanyName", "The Stella Team (http://stella.sourceforge.net)" VALUE "CompanyName", "The Stella Team (http://stella.sourceforge.net)"
VALUE "FileDescription", "Stella" VALUE "FileDescription", "Stella"
VALUE "FileVersion", "3.4.1" VALUE "FileVersion", "3.5"
VALUE "InternalName", "Stella" VALUE "InternalName", "Stella"
VALUE "LegalCopyright", "Copyright (C) 1995-2011 The Stella Team" VALUE "LegalCopyright", "Copyright (C) 1995-2011 The Stella Team"
VALUE "OriginalFilename", "Stella.exe" VALUE "OriginalFilename", "Stella.exe"
VALUE "ProductName", "Stella" VALUE "ProductName", "Stella"
VALUE "ProductVersion", "3.4.1" VALUE "ProductVersion", "3.5"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"