Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
Stella
Commits
3a54adec
Commit
3a54adec
authored
Jan 19, 2021
by
Christian Speckner
Browse files
Merge remote-tracking branch 'origin/master' into feature/fix-surfaces
parents
9f74a780
fb73d90c
Pipeline
#11387
passed with stages
in 2 minutes and 3 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
docs/index.html
View file @
3a54adec
...
...
@@ -2730,6 +2730,10 @@
indicating serious errors override this setting, and are always
shown.
</td>
</tr>
<tr>
<td><pre>
-pausedim
<
1|0
>
</pre></td>
<td>
Enable or disable emulation dimming in pause mode.
</td>
</tr>
<tr>
<td><pre>
-audio.enabled
<
1|0
>
</pre></td>
...
...
src/emucore/FrameBuffer.cxx
View file @
3a54adec
...
...
@@ -339,14 +339,16 @@ void FrameBuffer::update(UpdateMode mode)
case
EventHandlerState
::
PAUSE
:
{
// Show a pause message immediately and then every 7 seconds
bool
shade
=
myOSystem
.
settings
().
getBool
(
"pausedim"
);
if
(
myPausedCount
--
<=
0
)
{
myPausedCount
=
uInt32
(
7
*
myOSystem
.
frameRate
());
showTextMessage
(
"Paused"
,
MessagePosition
::
MiddleCenter
);
myTIASurface
->
render
(
tru
e
);
myTIASurface
->
render
(
shad
e
);
}
if
(
rerender
)
myTIASurface
->
render
(
tru
e
);
myTIASurface
->
render
(
shad
e
);
break
;
// EventHandlerState::PAUSE
}
...
...
src/emucore/Paddles.cxx
View file @
3a54adec
...
...
@@ -47,113 +47,50 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system,
// Consider whether this is the left or right port
if
(
myJack
==
Jack
::
Left
)
{
if
(
!
swappaddle
)
// First paddle is 0, second is 1
{
// These aren't affected by changes in axis orientation
myP0AxisValue
=
Event
::
PaddleZeroAnalog
;
myP1AxisValue
=
Event
::
PaddleOneAnalog
;
myP0FireEvent
=
Event
::
PaddleZeroFire
;
myP1FireEvent
=
Event
::
PaddleOneFire
;
// Direction of movement is swapped
// That is, moving in a certain direction on an axis can
// result in either increasing or decreasing paddle movement
if
(
!
swapdir
)
{
myP0DecEvent
=
Event
::
PaddleZeroDecrease
;
myP0IncEvent
=
Event
::
PaddleZeroIncrease
;
myP1DecEvent
=
Event
::
PaddleOneDecrease
;
myP1IncEvent
=
Event
::
PaddleOneIncrease
;
}
else
{
myP0DecEvent
=
Event
::
PaddleZeroIncrease
;
myP0IncEvent
=
Event
::
PaddleZeroDecrease
;
myP1DecEvent
=
Event
::
PaddleOneIncrease
;
myP1IncEvent
=
Event
::
PaddleOneDecrease
;
}
}
else
// First paddle is 1, second is 0
{
// These aren't affected by changes in axis orientation
myP0AxisValue
=
Event
::
PaddleOneAnalog
;
myP1AxisValue
=
Event
::
PaddleZeroAnalog
;
myP0FireEvent
=
Event
::
PaddleOneFire
;
myP1FireEvent
=
Event
::
PaddleZeroFire
;
// Direction of movement is swapped
// That is, moving in a certain direction on an axis can
// result in either increasing or decreasing paddle movement
if
(
!
swapdir
)
{
myP0DecEvent
=
Event
::
PaddleOneDecrease
;
myP0IncEvent
=
Event
::
PaddleOneIncrease
;
myP1DecEvent
=
Event
::
PaddleZeroDecrease
;
myP1IncEvent
=
Event
::
PaddleZeroIncrease
;
}
else
{
myP0DecEvent
=
Event
::
PaddleOneIncrease
;
myP0IncEvent
=
Event
::
PaddleOneDecrease
;
myP1DecEvent
=
Event
::
PaddleZeroIncrease
;
myP1IncEvent
=
Event
::
PaddleZeroDecrease
;
}
}
// First paddle is 0, second is 1
myP0AxisValue
=
Event
::
PaddleZeroAnalog
;
myP1AxisValue
=
Event
::
PaddleOneAnalog
;
myP0FireEvent
=
Event
::
PaddleZeroFire
;
myP1FireEvent
=
Event
::
PaddleOneFire
;
// These can be affected by changes in axis orientation
myP0DecEvent
=
Event
::
PaddleZeroDecrease
;
myP0IncEvent
=
Event
::
PaddleZeroIncrease
;
myP1DecEvent
=
Event
::
PaddleOneDecrease
;
myP1IncEvent
=
Event
::
PaddleOneIncrease
;
}
else
// Jack is right port
{
if
(
!
swappaddle
)
// First paddle is 2, second is 3
{
// These aren't affected by changes in axis orientation
myP0AxisValue
=
Event
::
PaddleTwoAnalog
;
myP1AxisValue
=
Event
::
PaddleThreeAnalog
;
myP0FireEvent
=
Event
::
PaddleTwoFire
;
myP1FireEvent
=
Event
::
PaddleThreeFire
;
// Direction of movement is swapped
// That is, moving in a certain direction on an axis can
// result in either increasing or decreasing paddle movement
if
(
!
swapdir
)
{
myP0DecEvent
=
Event
::
PaddleTwoDecrease
;
myP0IncEvent
=
Event
::
PaddleTwoIncrease
;
myP1DecEvent
=
Event
::
PaddleThreeDecrease
;
myP1IncEvent
=
Event
::
PaddleThreeIncrease
;
}
else
{
myP0DecEvent
=
Event
::
PaddleTwoIncrease
;
myP0IncEvent
=
Event
::
PaddleTwoDecrease
;
myP1DecEvent
=
Event
::
PaddleThreeIncrease
;
myP1IncEvent
=
Event
::
PaddleThreeDecrease
;
}
}
else
// First paddle is 3, second is 2
{
// These aren't affected by changes in axis orientation
myP0AxisValue
=
Event
::
PaddleThreeAnalog
;
myP1AxisValue
=
Event
::
PaddleTwoAnalog
;
myP0FireEvent
=
Event
::
PaddleThreeFire
;
myP1FireEvent
=
Event
::
PaddleTwoFire
;
// Direction of movement is swapped
// That is, moving in a certain direction on an axis can
// result in either increasing or decreasing paddle movement
if
(
!
swapdir
)
{
myP0DecEvent
=
Event
::
PaddleThreeDecrease
;
myP0IncEvent
=
Event
::
PaddleThreeIncrease
;
myP1DecEvent
=
Event
::
PaddleTwoDecrease
;
myP1IncEvent
=
Event
::
PaddleTwoIncrease
;
}
else
{
myP0DecEvent
=
Event
::
PaddleThreeIncrease
;
myP0IncEvent
=
Event
::
PaddleThreeDecrease
;
myP1DecEvent
=
Event
::
PaddleTwoIncrease
;
myP1IncEvent
=
Event
::
PaddleTwoDecrease
;
}
}
// First paddle is 2, second is 3
myP0AxisValue
=
Event
::
PaddleTwoAnalog
;
myP1AxisValue
=
Event
::
PaddleThreeAnalog
;
myP0FireEvent
=
Event
::
PaddleTwoFire
;
myP1FireEvent
=
Event
::
PaddleThreeFire
;
// These can be affected by changes in axis orientation
myP0DecEvent
=
Event
::
PaddleTwoDecrease
;
myP0IncEvent
=
Event
::
PaddleTwoIncrease
;
myP1DecEvent
=
Event
::
PaddleThreeDecrease
;
myP1IncEvent
=
Event
::
PaddleThreeIncrease
;
}
// Some games swap the paddles
if
(
swappaddle
)
{
// First paddle is 1|3, second is 0|2
swapEvents
(
myP0AxisValue
,
myP1AxisValue
);
swapEvents
(
myP0FireEvent
,
myP1FireEvent
);
swapEvents
(
myP0DecEvent
,
myP1DecEvent
);
swapEvents
(
myP0IncEvent
,
myP1IncEvent
);
}
// Direction of movement can be swapped
// That is, moving in a certain direction on an axis can
// result in either increasing or decreasing paddle movement
if
(
swapdir
)
{
swapEvents
(
myP0DecEvent
,
myP0IncEvent
);
swapEvents
(
myP1DecEvent
,
myP1IncEvent
);
}
// The following are independent of whether or not the port
...
...
@@ -179,6 +116,16 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system,
setPin
(
DigitalPin
::
Six
,
true
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
Paddles
::
swapEvents
(
Event
::
Type
&
event1
,
Event
::
Type
&
event2
)
{
Event
::
Type
swappedEvent
;
swappedEvent
=
event1
;
event1
=
event2
;
event2
=
swappedEvent
;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
Paddles
::
update
()
{
...
...
@@ -200,6 +147,31 @@ void Paddles::update()
// And to top it all off, we don't want one devices input to conflict
// with the others ...
if
(
!
updateAnalogAxes
())
{
updateMouse
(
firePressedP0
,
firePressedP1
);
updateDigitalAxes
();
// Only change state if the charge has actually changed
if
(
myCharge
[
1
]
!=
myLastCharge
[
1
])
{
setPin
(
AnalogPin
::
Five
,
Int32
(
MAX_RESISTANCE
*
(
myCharge
[
1
]
/
double
(
TRIGMAX
))));
myLastCharge
[
1
]
=
myCharge
[
1
];
}
if
(
myCharge
[
0
]
!=
myLastCharge
[
0
])
{
setPin
(
AnalogPin
::
Nine
,
Int32
(
MAX_RESISTANCE
*
(
myCharge
[
0
]
/
double
(
TRIGMAX
))));
myLastCharge
[
0
]
=
myCharge
[
0
];
}
}
setPin
(
DigitalPin
::
Four
,
!
getAutoFireState
(
firePressedP0
));
setPin
(
DigitalPin
::
Three
,
!
getAutoFireStateP1
(
firePressedP1
));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Paddles
::
updateAnalogAxes
()
{
// Analog axis events from Stelladaptor-like devices
// These devices generate data in the range -32768 to 32767,
// so we have to scale appropriately
...
...
@@ -207,10 +179,6 @@ void Paddles::update()
// we only process the first one we see (when it differs from
// previous values by a pre-defined amount)
// Otherwise, it would always override input from digital and mouse
bool
sa_changed
=
false
;
int
sa_xaxis
=
myEvent
.
get
(
myP0AxisValue
);
int
sa_yaxis
=
myEvent
.
get
(
myP1AxisValue
);
int
new_val
;
static
constexpr
std
::
array
<
double
,
MAX_DEJITTER
-
MIN_DEJITTER
+
1
>
bFac
=
{
// higher values mean more dejitter strength
...
...
@@ -221,24 +189,28 @@ void Paddles::update()
static
constexpr
std
::
array
<
double
,
MAX_DEJITTER
-
MIN_DEJITTER
+
1
>
dFac
=
{
// lower values mean more dejitter strength
1
,
// off
1.0
/
181
,
1.0
/
256
,
1.0
/
362
,
1.0
/
512
,
1.0
/
724
,
1.0
/
181
,
1.0
/
256
,
1.0
/
362
,
1.0
/
512
,
1.0
/
724
,
1.0
/
1024
,
1.0
/
1448
,
1.0
/
2048
,
1.0
/
2896
,
1.0
/
4096
};
const
double
baseFactor
=
bFac
[
DEJITTER_BASE
];
const
double
diffFactor
=
dFac
[
DEJITTER_DIFF
];
int
sa_xaxis
=
myEvent
.
get
(
myP0AxisValue
);
int
sa_yaxis
=
myEvent
.
get
(
myP1AxisValue
);
bool
sa_changed
=
false
;
if
(
abs
(
myLastAxisX
-
sa_xaxis
)
>
10
)
{
// dejitter, suppress small changes only
double
dejitter
=
std
::
pow
(
baseFactor
,
abs
(
sa_xaxis
-
myLastAxisX
)
*
diffFactor
);
new_val
=
sa_xaxis
*
(
1
-
dejitter
)
+
myLastAxisX
*
dejitter
;
int
new_val
=
sa_xaxis
*
(
1
-
dejitter
)
+
myLastAxisX
*
dejitter
;
// only use new dejittered value for larger differences
if
(
abs
(
new_val
-
sa_xaxis
)
>
10
)
sa_xaxis
=
new_val
;
setPin
(
AnalogPin
::
Nine
,
Int32
(
MAX_RESISTANCE
*
(
BSPF
::
clamp
(
32768
-
Int32
(
Int32
(
sa_xaxis
)
*
SENSITIVITY
+
XCENTER
),
0
,
65536
)
/
65536.0
)));
(
BSPF
::
clamp
(
32768
-
Int32
(
Int32
(
sa_xaxis
)
*
SENSITIVITY
+
XCENTER
),
0
,
65536
)
/
65536.0
)));
sa_changed
=
true
;
}
...
...
@@ -246,29 +218,33 @@ void Paddles::update()
{
// dejitter, suppress small changes only
double
dejitter
=
std
::
pow
(
baseFactor
,
abs
(
sa_yaxis
-
myLastAxisY
)
*
diffFactor
);
new_val
=
sa_yaxis
*
(
1
-
dejitter
)
+
myLastAxisY
*
dejitter
;
int
new_val
=
sa_yaxis
*
(
1
-
dejitter
)
+
myLastAxisY
*
dejitter
;
// only use new dejittered value for larger differences
if
(
abs
(
new_val
-
sa_yaxis
)
>
10
)
if
(
abs
(
new_val
-
sa_yaxis
)
>
10
)
sa_yaxis
=
new_val
;
setPin
(
AnalogPin
::
Five
,
Int32
(
MAX_RESISTANCE
*
(
BSPF
::
clamp
(
32768
-
Int32
(
Int32
(
sa_yaxis
)
*
SENSITIVITY
+
YCENTER
),
0
,
65536
)
/
65536.0
)));
(
BSPF
::
clamp
(
32768
-
Int32
(
Int32
(
sa_yaxis
)
*
SENSITIVITY
+
YCENTER
),
0
,
65536
)
/
65536.0
)));
sa_changed
=
true
;
}
myLastAxisX
=
sa_xaxis
;
myLastAxisY
=
sa_yaxis
;
if
(
sa_changed
)
return
;
return
sa_changed
;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
Paddles
::
updateMouse
(
bool
&
firePressedP0
,
bool
&
firePressedP1
)
{
// Mouse motion events give relative movement
// That is, they're only relevant if they're non-zero
if
(
myMPaddleID
>
-
1
)
{
// We're in auto mode, where a single axis is used for one paddle only
myCharge
[
myMPaddleID
]
=
BSPF
::
clamp
(
myCharge
[
myMPaddleID
]
-
(
myEvent
.
get
(
myAxisMouseMotion
)
*
MOUSE_SENSITIVITY
),
TRIGMIN
,
TRIGRANGE
);
(
myEvent
.
get
(
myAxisMouseMotion
)
*
MOUSE_SENSITIVITY
),
TRIGMIN
,
TRIGRANGE
);
if
(
myMPaddleID
==
0
)
firePressedP0
=
firePressedP0
||
myEvent
.
get
(
Event
::
MouseButtonLeftValue
)
...
...
@@ -285,9 +261,8 @@ void Paddles::update()
if
(
myMPaddleIDX
>
-
1
)
{
myCharge
[
myMPaddleIDX
]
=
BSPF
::
clamp
(
myCharge
[
myMPaddleIDX
]
-
(
myEvent
.
get
(
Event
::
MouseAxisXMove
)
*
MOUSE_SENSITIVITY
),
TRIGMIN
,
TRIGRANGE
);
(
myEvent
.
get
(
Event
::
MouseAxisXMove
)
*
MOUSE_SENSITIVITY
),
TRIGMIN
,
TRIGRANGE
);
if
(
myMPaddleIDX
==
0
)
firePressedP0
=
firePressedP0
||
myEvent
.
get
(
Event
::
MouseButtonLeftValue
);
...
...
@@ -298,9 +273,8 @@ void Paddles::update()
if
(
myMPaddleIDY
>
-
1
)
{
myCharge
[
myMPaddleIDY
]
=
BSPF
::
clamp
(
myCharge
[
myMPaddleIDY
]
-
(
myEvent
.
get
(
Event
::
MouseAxisYMove
)
*
MOUSE_SENSITIVITY
),
TRIGMIN
,
TRIGRANGE
);
(
myEvent
.
get
(
Event
::
MouseAxisYMove
)
*
MOUSE_SENSITIVITY
),
TRIGMIN
,
TRIGRANGE
);
if
(
myMPaddleIDY
==
0
)
firePressedP0
=
firePressedP0
||
myEvent
.
get
(
Event
::
MouseButtonRightValue
);
...
...
@@ -309,9 +283,11 @@ void Paddles::update()
||
myEvent
.
get
(
Event
::
MouseButtonRightValue
);
}
}
setPin
(
DigitalPin
::
Four
,
!
getAutoFireState
(
firePressedP0
));
setPin
(
DigitalPin
::
Three
,
!
getAutoFireStateP1
(
firePressedP1
));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
Paddles
::
updateDigitalAxes
()
{
// Finally, consider digital input, where movement happens
// until a digital event is released
if
(
myKeyRepeat0
)
...
...
@@ -354,15 +330,6 @@ void Paddles::update()
if
((
myCharge
[
myAxisDigitalOne
]
+
myPaddleRepeat1
)
<
TRIGRANGE
)
myCharge
[
myAxisDigitalOne
]
+=
myPaddleRepeat1
;
}
// Only change state if the charge has actually changed
if
(
myCharge
[
1
]
!=
myLastCharge
[
1
])
setPin
(
AnalogPin
::
Five
,
Int32
(
MAX_RESISTANCE
*
(
myCharge
[
1
]
/
double
(
TRIGMAX
))));
if
(
myCharge
[
0
]
!=
myLastCharge
[
0
])
setPin
(
AnalogPin
::
Nine
,
Int32
(
MAX_RESISTANCE
*
(
myCharge
[
0
]
/
double
(
TRIGMAX
))));
myLastCharge
[
1
]
=
myCharge
[
1
];
myLastCharge
[
0
]
=
myCharge
[
0
];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
...
...
src/emucore/Paddles.hxx
View file @
3a54adec
...
...
@@ -197,6 +197,26 @@ class Paddles : public Controller
static
int
DEJITTER_BASE
,
DEJITTER_DIFF
;
static
int
MOUSE_SENSITIVITY
;
/**
Swap two events.
*/
void
swapEvents
(
Event
::
Type
&
event1
,
Event
::
Type
&
event2
);
/**
Update the axes pin state according to the events currently set.
*/
bool
updateAnalogAxes
();
/**
Update the entire state according to mouse events currently set.
*/
void
updateMouse
(
bool
&
firePressedP0
,
bool
&
firePressedP1
);
/**
Update the axes pin state according to the keyboard events currently set.
*/
void
updateDigitalAxes
();
private:
// Following constructors and assignment operators not supported
Paddles
()
=
delete
;
...
...
src/emucore/Settings.cxx
View file @
3a54adec
...
...
@@ -47,6 +47,7 @@ Settings::Settings()
setPermanent
(
"windowedpos"
,
Common
::
Point
(
50
,
50
));
setPermanent
(
"display"
,
0
);
setPermanent
(
"uimessages"
,
"true"
);
setPermanent
(
"pausedim"
,
"true"
);
// TIA specific options
setPermanent
(
"tia.inter"
,
"false"
);
setPermanent
(
"tia.zoom"
,
"3"
);
...
...
@@ -446,6 +447,7 @@ void Settings::usage() const
<<
" -speed <number> Run emulation at the given speed
\n
"
<<
" -turbo <1|0> Enable 'Turbo' mode for maximum emulation speed
\n
"
<<
" -uimessages <1|0> Show onscreen UI messages for different events
\n
"
<<
" -pausedim <1|0> Enable emulation dimming in pause mode
\n
"
<<
endl
#ifdef SOUND_SUPPORT
<<
" -audio.enabled <1|0> Enable audio
\n
"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment