mirror of https://github.com/stella-emu/stella.git
Merge branch 'master' into feature/precise-audio
This commit is contained in:
commit
7d7ebb8d03
22
Announce.txt
22
Announce.txt
|
@ -9,7 +9,7 @@
|
|||
SSSS ttt eeeee llll llll aaaaa
|
||||
|
||||
===========================================================================
|
||||
Release 5.0.2 for Linux, MacOSX and Windows
|
||||
Release 5.1 for Linux, MacOSX and Windows
|
||||
===========================================================================
|
||||
|
||||
The Atari 2600 Video Computer System (VCS), introduced in 1977, was the
|
||||
|
@ -21,30 +21,30 @@ 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
|
||||
number of other platforms and is currently maintained by Stephen Anthony.
|
||||
|
||||
This is the 5.0.2 release of Stella for Linux, Mac OSX and Windows. The
|
||||
This is the 5.1 release of Stella for Linux, Mac OSX and Windows. The
|
||||
distributions currently available are:
|
||||
|
||||
* Binaries for Windows XP_SP3(*)/Vista/7/8/10 :
|
||||
Stella-5.0.2-win32.exe (32-bit EXE installer)
|
||||
Stella-5.0.2-x64.exe (64-bit EXE installer)
|
||||
Stella-5.0.2-windows.zip (32/64 bit versions)
|
||||
Stella-5.1-win32.exe (32-bit EXE installer)
|
||||
Stella-5.1-x64.exe (64-bit EXE installer)
|
||||
Stella-5.1-windows.zip (32/64 bit versions)
|
||||
|
||||
(*) Note: Support for Windows XP is problematic on some systems,
|
||||
and will probably be discontinued in a future release.
|
||||
|
||||
* Binary distribution for MacOS X 10.7 and above :
|
||||
Stella-5.0.2-macosx.dmg (64-bit Intel)
|
||||
Stella-5.1-macosx.dmg (64-bit Intel)
|
||||
|
||||
* Binary distribution in 32-bit & 64-bit Ubuntu DEB format :
|
||||
stella_5.0.2-1_i386.deb
|
||||
stella_5.0.2-1_amd64.deb
|
||||
stella_5.1-1_i386.deb
|
||||
stella_5.1-1_amd64.deb
|
||||
|
||||
* Binary distribution in 32-bit & 64-bit RPM format :
|
||||
stella-5.0.2-2.i386.rpm
|
||||
stella-5.0.2-2.x86_64.rpm
|
||||
stella-5.1-2.i386.rpm
|
||||
stella-5.1-2.x86_64.rpm
|
||||
|
||||
* Source code distribution for all platforms :
|
||||
stella-5.0.2-src.tar.xz
|
||||
stella-5.1-src.tar.xz
|
||||
|
||||
|
||||
Distribution Site
|
||||
|
|
71
Changes.txt
71
Changes.txt
|
@ -1,18 +1,8 @@
|
|||
5.0.2 to 5.1: (January xx, 2018)
|
||||
5.0.2 to 5.1: (February 4, 2018)
|
||||
|
||||
* Thumbulator support is not conditional any more.
|
||||
|
||||
* Don't trap write accesses to the datastream pointers in CDF and BUS.
|
||||
This fixes -dev.thumb.trapfatal 1.
|
||||
|
||||
* Complete rework of TV mode and ystart autodetection. The new
|
||||
implementation is more robust and reduces startup time.
|
||||
|
||||
* Add two "grace lines" of black to the top of the frame when
|
||||
autodetecting ystart.
|
||||
|
||||
* Support UNIX style builds (configure / make) on OSX with both
|
||||
XCode / clang and g++.
|
||||
* Added "Time Machine" mode, which automatically creates save states
|
||||
in user-defined intervals. The user can navigate back and forth within
|
||||
these states inside the emulator and the debugger.
|
||||
|
||||
* Huge improvements to the disassembly view in the debugger and
|
||||
disassembly files created:
|
||||
|
@ -23,9 +13,30 @@
|
|||
- improved cycle count (page penalties, sums created in disassembly)
|
||||
- improved handling of instruction masking opcodes (e.g. BIT)
|
||||
|
||||
* Added "Time Machine" mode, which automatically creates save states
|
||||
in user-defined intervals. The user can navigate back and forth within
|
||||
these states inside the emulator and the debugger.
|
||||
* Fixed change tracking bug during rewind; changes were accumulated
|
||||
instead of being displayed only for the last rewind step.
|
||||
|
||||
* Extended 'rewind' to take a second parameter which allows rewinding
|
||||
multiple states.
|
||||
|
||||
* Added 'unwind' command, which undoes the latest rewind(s)
|
||||
|
||||
* Added '<' (unwind) button to debugger.
|
||||
|
||||
* Thumbulator support is not conditional any more.
|
||||
|
||||
* Moved various developer related settings in new Developer Settings
|
||||
dialog. These settings now come in two groups (player/developer) and
|
||||
allow switching all settings at once.
|
||||
|
||||
* Don't trap write accesses to the datastream pointers in CDF and BUS.
|
||||
This fixes -dev.thumb.trapfatal 1.
|
||||
|
||||
* Complete rework of TV mode and ystart autodetection. The new
|
||||
implementation is more robust and reduces startup time.
|
||||
|
||||
* Add two "grace lines" of black to the top of the frame when
|
||||
autodetecting ystart.
|
||||
|
||||
* Fixed Genesis controller autodetect (Stay Frosty 2, Scramble, etc).
|
||||
|
||||
|
@ -48,9 +59,6 @@
|
|||
information). In the case of 'saveses', the filename is now named
|
||||
based on the date and time of when the command was entered.
|
||||
|
||||
* Fixed change tracking bug during rewind; changes were accumulated
|
||||
instead of being displayed only for the last rewind step.
|
||||
|
||||
* Fixed bug with saving snapshots in 1x mode; there was graphical
|
||||
corruption in some cases. Such snapshots also now include any TV
|
||||
effects / phosphor blending currently in use.
|
||||
|
@ -72,22 +80,16 @@
|
|||
all ROMs or only the current one. Also added a message (configurable)
|
||||
when the flash memory is accessed.
|
||||
|
||||
* Moved various developer related settings in new Developer Settings
|
||||
dialog. These settings now come in two groups (player/developer) and
|
||||
allow switching all settings at once.
|
||||
* Access to the AtariVox/SaveKey can be signaled with a message.
|
||||
|
||||
* Added new interface palette 'Light'
|
||||
* Added new interface palette 'Light'.
|
||||
|
||||
* Improved tab auto-complete in debugger
|
||||
* Frame stats display made transparent. Also it now displays the real
|
||||
frame rate and if the developer settings group is enabled.
|
||||
|
||||
* Added conditional traps and savestate creation to debugger
|
||||
* Improved tab auto-complete in debugger.
|
||||
|
||||
* Extended 'rewind' to take a second parameter which allows rewinding
|
||||
multiple states.
|
||||
|
||||
* Added 'unwind' command, which undoes the latest rewind(s)
|
||||
|
||||
* Added '<' (unwind) button to debugger.
|
||||
* Added conditional traps and savestate creation to debugger.
|
||||
|
||||
* Added 'Options...' button to debugger which gives access to the options
|
||||
menu during debugging.
|
||||
|
@ -107,7 +109,7 @@
|
|||
* Improved change tracking; more values are tracked and change tracking
|
||||
now works in case of a break too.
|
||||
|
||||
* Added widgets for trackball and SaveKey/AtariVox controllers
|
||||
* Added widgets for trackball and SaveKey/AtariVox controllers.
|
||||
|
||||
* Improved emulation of 'FE' bankswitch scheme (no user-visible changes,
|
||||
but internally the emulation is much more accurate compared to the
|
||||
|
@ -122,6 +124,9 @@
|
|||
* Added ROM properties for 'Zippy the Porcupine' ROMs, and updated
|
||||
info for all "Chris Spry (Sprybug)" ROMs.
|
||||
|
||||
* Support UNIX style builds (configure / make) on OSX with both
|
||||
XCode / clang and g++.
|
||||
|
||||
* Fixed error when building with uClibc-ng for ARM (thanks to Sergio
|
||||
Prado).
|
||||
|
||||
|
|
|
@ -348,22 +348,26 @@ esac
|
|||
# Determine the C++ compiler
|
||||
#
|
||||
echo_n "Looking for C++ compiler... "
|
||||
if test -n "$_host"; then
|
||||
compilers="$CXX $_host_prefix-g++ $_host_prefix-c++ $_host_cpu-$_host_os-g++ $_host_cpu-$_host_os-c++"
|
||||
if test -n "$CXX"; then
|
||||
echo $CXX
|
||||
else
|
||||
compilers="$CXX g++ c++"
|
||||
fi
|
||||
|
||||
for compiler in $compilers; do
|
||||
if test_compiler "$compiler -std=c++14"; then
|
||||
CXX=$compiler
|
||||
echo $CXX
|
||||
break
|
||||
if test -n "$_host"; then
|
||||
compilers="$_host_prefix-g++ $_host_prefix-c++ $_host_cpu-$_host_os-g++ $_host_cpu-$_host_os-c++"
|
||||
else
|
||||
compilers="g++ c++"
|
||||
fi
|
||||
|
||||
for compiler in $compilers; do
|
||||
if test_compiler "$compiler -std=c++14"; then
|
||||
CXX=$compiler
|
||||
echo $CXX
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$CXX"; then
|
||||
echo "none found!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
if test -z $CXX; then
|
||||
echo "none found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
stella (5.1-1) stable; urgency=high
|
||||
|
||||
* Version 5.1 release
|
||||
|
||||
-- Stephen Anthony <stephena@users.sf.net> Sun, 4 Feb 2018 17:09:59 -0230
|
||||
|
||||
|
||||
stella (5.0.2-1) stable; urgency=high
|
||||
|
||||
* Version 5.0.2 release
|
||||
|
|
|
@ -348,27 +348,27 @@ size can be configured e.g. in the
|
|||
<td>Frame+1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Control-r</td>
|
||||
<td>Alt-Left arrow</td>
|
||||
<td>Rewind 1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Control-Shift-r</td>
|
||||
<td>Shift-Alt-Left arrow</td>
|
||||
<td>Rewind 10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Control-Alt-r</td>
|
||||
<td>Alt-Down arrow</td>
|
||||
<td>Rewind all</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Control-y</td>
|
||||
<td>Alt-Right arrow</td>
|
||||
<td>Unwind 1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Control-Shift-y</td>
|
||||
<td>Shift-Alt-Right arrow</td>
|
||||
<td>Unwind 10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Control-Alt-y</td>
|
||||
<td>Alt-Up arrow</td>
|
||||
<td>Unwind all</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -377,6 +377,7 @@ size can be configured e.g. in the
|
|||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
For MacOS use 'Cmd' instead of 'Alt' key.
|
||||
<p>To the left of the global buttons, you find the "Options..." button.</p>
|
||||
<ul>
|
||||
<p><img src="graphics/debugger_options.png"></p>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 7.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
113
docs/index.html
113
docs/index.html
|
@ -61,7 +61,7 @@
|
|||
|
||||
<br><br><br>
|
||||
|
||||
<center><b>February 1999 - January 2018</b></center>
|
||||
<center><b>February 1999 - February 2018</b></center>
|
||||
<center><b>The Stella Team</b></center>
|
||||
<center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center>
|
||||
|
||||
|
@ -1622,32 +1622,38 @@
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Rewind by one state (pauses emulation)</td>
|
||||
<td>Enter/Exit the <a href="#TimeMachine"><b>Time Machine</b></a> dialog</td>
|
||||
<td>t to enter, t/Escape/Space to exit</td>
|
||||
<td>t to enter, t/Escape/Space to exit</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Rewind by one state (enters the <a href="#TimeMachine"><b>Time Machine</b></a> dialog)</td>
|
||||
<td>Alt + Left arrow</td>
|
||||
<td>Cmd + Left arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rewind by 10 states (pauses emulation)</td>
|
||||
<td>Rewind by 10 states (enters the <a href="#TimeMachine"><b>Time Machine</b></a> dialog)</td>
|
||||
<td>Shift-Alt + Left arrow</td>
|
||||
<td>Shift-Cmd + Left arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rewind all states (pauses emulation)</td>
|
||||
<td>Rewind all states (enters the <a href="#TimeMachine"><b>Time Machine</b></a> dialog)</td>
|
||||
<td>Alt + Down arrow</td>
|
||||
<td>Cmd + Down arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unwind by one state (pauses emulation)</td>
|
||||
<td>Unwind by one state (enters the <a href="#TimeMachine"><b>Time Machine</b></a> dialog)</td>
|
||||
<td>Alt + Right arrow</td>
|
||||
<td>Cmd + Right arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unwind by 10 states (pauses emulation)</td>
|
||||
<td>Unwind by 10 states (enters the <a href="#TimeMachine"><b>Time Machine</b></a> dialog)</td>
|
||||
<td>Shift-Alt + Right arrow</td>
|
||||
<td>Shift-Cmd + Right arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unwind all states (pauses emulation)</td>
|
||||
<td>Unwind all states (enters the <a href="#TimeMachine"><b>Time Machine</b></a> dialog)</td>
|
||||
<td>Alt + Up arrow</td>
|
||||
<td>Cmd + Up arrow</td>
|
||||
</tr>
|
||||
|
@ -1794,36 +1800,49 @@
|
|||
<a name="TimeMachine">Stella's 'Time Machine'</a></h2>
|
||||
|
||||
<p>A special feature of Stella is the 'Time Machine' mode. In this mode, Stella
|
||||
automatically creates savestates in regular, user-defined intervals. You can then
|
||||
interrupt the current emulation and navigate back and forth within the timeline.
|
||||
automatically creates savestates in regular, user-defined intervals. At any time,
|
||||
the user can interrupt the current emulation and navigate back and forth
|
||||
within the saved timeline.
|
||||
This can be done either by using the Time Machine hotkeys described in
|
||||
<a href="#Hotkeys"><b>Hotkeys</b> - Other Keys</a> or by using the Time Machine
|
||||
dialog. To enter this dialog, either use one of the hotkeys or press 'T'.</p>
|
||||
dialog. This dialog is automatically entered when using one of the Time Machine
|
||||
hotkeys. The hotkeys continue to function within the dialog.</p>
|
||||
|
||||
<p><b>Time Machine</b> dialog:</p>
|
||||
<table border="5" cellpadding="2" frame="box" rules="none">
|
||||
<tr>
|
||||
<td>TODO: Screenshot</td>
|
||||
<td> </td>
|
||||
<td valign="top">
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Item</th><th>Description</th></tr>
|
||||
<tr><td>Button</td><td>TODO</td></tr>
|
||||
<tr><td>Button</td><td></td></tr>
|
||||
<tr><td>Button</td><td></td></tr>
|
||||
<tr><td>Button</td><td></td></tr>
|
||||
<tr><td>Button</td><td></td></tr>
|
||||
<tr><td>Button</td><td></td></tr>
|
||||
<tr><td>Button</td><td></td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<td><img src="graphics/timemachine.png"></td>
|
||||
|
||||
<p>The dialog items are explained in the following two tables.</p>
|
||||
|
||||
<p><b>Top row (left to right)</b></p>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Item</th><th>Description</th></tr>
|
||||
<tr><td>Current state</td><td>Shows the currently loaded state's number</td></tr>
|
||||
<tr><td>'Timeline' slider</td><td>Shows the position of the current state in the
|
||||
recorded timeline. A state can be selected by dragging the slider with the mouse.
|
||||
To visualize state compression, small marks split the timeline into five, equally
|
||||
sized state number intervals.</td></tr>
|
||||
<tr><td>Total states</td><td>Shows the total number of save states in the
|
||||
Time Machine</td></tr>
|
||||
</table>
|
||||
<p><b>Bottom row (left to right)</b></p>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Item</th><th>Description</th></tr>
|
||||
<tr><td>Current time</td><td>Shows the time of the currently selected status,
|
||||
relative to the first one</td></tr>
|
||||
<tr><td>'Rewind All' button</td><td>Navigates back to the begin of the timeline</td></tr>
|
||||
<tr><td>'Rewind One' button</td><td>Navigates back by one state</td></tr>
|
||||
<tr><td>'Continue' button</td><td>Exits the dialog and continues emulation.</td></tr>
|
||||
<tr><td>Navigation info</td><td>Informs about the interval of the user's last
|
||||
Time Machine navigation. The interval can vary if the timeline is compressed.</td></tr>
|
||||
<tr><td>'Unwind One' button</td><td>Navigates forward by one state</td></tr>
|
||||
<tr><td>'Unwind All' button</td><td>Navigates forward to the end of the timeline</td></tr>
|
||||
<tr><td>Total time</td><td>Shows the total time covered by the save states
|
||||
(aka 'Horizon')</td></tr>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
|
||||
<p>The 'Time Machine' mode can be configured by the user. For details see
|
||||
<a href="#Debugger"><b>Developer Options</b> - Time Machine dialog</a></h2>.</p>
|
||||
<a href="#Debugger"><b>Developer Options</b> - Time Machine</a></h2> tab.</p>
|
||||
|
||||
<!-- ///////////////////////////////////////////////////////////////////////// -->
|
||||
<br><br>
|
||||
|
@ -2538,10 +2557,14 @@
|
|||
</tr><tr>
|
||||
<td><pre>-<plr.|dev.>thumb.trapfatal <1|0></pre></td>
|
||||
<td>The default of true allows the Thumb ARM emulation to
|
||||
throw an exception and enter the debugger on fatal errors. When disabled, such
|
||||
fatal errors are simply logged, and emulation continues. Do not use this
|
||||
unless you know exactly what you're doing, as it changes the behaviour as compared
|
||||
to real hardware.</td>
|
||||
throw an exception and enter the debugger on fatal errors. When disabled, such
|
||||
fatal errors are simply logged, and emulation continues. Do not use this
|
||||
unless you know exactly what you're doing, as it changes the behaviour as
|
||||
compared to real hardware.</td>
|
||||
</tr><tr>
|
||||
<td><pre>-<plr.|dev.>eepromaccess <1|0></pre></td>
|
||||
<td>When enabled, each read or write access to the AtariVox/SaveKey EEPROM is
|
||||
signalled by a message.</td>
|
||||
</tr><tr>
|
||||
<td><pre>-<plr.|dev.>tv.jitter <1|0></pre></td>
|
||||
<td>Enable TV jitter/roll effect, when there are too many or too few scanlines
|
||||
|
@ -2740,13 +2763,15 @@
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p><b>Audit ROMs</b> dialog:</p>
|
||||
<br>
|
||||
<p><b>Developer Settings</b> dialog:</p>
|
||||
<table border="5" cellpadding="2" frame="box" rules="none">
|
||||
<tr>
|
||||
<td><img src="graphics/romaudit.png"></td>
|
||||
<td><img src="graphics/options_developer.png"></td>
|
||||
<td> </td>
|
||||
<td valign="top"><br>This dialog is described in further detail in
|
||||
<b>Advanced Configuration - <a href="#ROMAudit">ROM Audit Mode</a></b>.</td>
|
||||
<td valign="top"><br>This tab is described in further detail in
|
||||
<b>Advanced Configuration - <a href="#Debugger">Developer Options/Integrated Debugger</a></b>.</td>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
|
@ -2760,18 +2785,17 @@
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
<p><b>Developer Settings</b> dialog:</p>
|
||||
<p><b>Audit ROMs</b> dialog:</p>
|
||||
<table border="5" cellpadding="2" frame="box" rules="none">
|
||||
<tr>
|
||||
<td><img src="graphics/options_developer.png"></td>
|
||||
<td><img src="graphics/romaudit.png"></td>
|
||||
<td> </td>
|
||||
<td valign="top"><br>This tab is described in further detail in
|
||||
<b>Advanced Configuration - <a href="#Debugger">Developer Options/Integrated Debugger</a></b>.</td>
|
||||
</td>
|
||||
<td valign="top"><br>This dialog is described in further detail in
|
||||
<b>Advanced Configuration - <a href="#ROMAudit">ROM Audit Mode</a></b>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
</blockquote>
|
||||
|
||||
<h2><b><a name="Remapping">Event Remapping/Input Devices</a></b></h2>
|
||||
|
@ -3115,6 +3139,7 @@
|
|||
<td>Thumb ARM emulation throws an exception and enters the debugger on fatal errors</td>
|
||||
<td><span style="white-space:nowrap">-plr.thumb.trapfatal<br/>-dev.thumb.trapfatal</span></td>
|
||||
</tr>
|
||||
<tr><td>Display AtariVox...</td><td>Display a message when the AtariVox/SaveKey EEPROM is read or written</td><td>-plr.eepromaccess<br/>-dev.eepromaccess</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -78,6 +78,9 @@ class LinkedObjectPool
|
|||
SLOW, but only required for messages
|
||||
*/
|
||||
uInt32 currentIdx() const {
|
||||
if(empty())
|
||||
return 0;
|
||||
|
||||
iter it = myCurrent;
|
||||
uInt32 idx = 1;
|
||||
|
||||
|
|
|
@ -284,7 +284,6 @@ string RewindManager::getUnitString(Int64 cycles)
|
|||
const Int32 PAL_FREQ = 1182298; // ~76*312*50
|
||||
const Int32 freq = isNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second
|
||||
|
||||
// TODO: do we need hours here? don't think so
|
||||
const Int32 NUM_UNITS = 5;
|
||||
const string UNIT_NAMES[NUM_UNITS] = { "cycle", "scanline", "frame", "second", "minute" };
|
||||
const Int64 UNIT_CYCLES[NUM_UNITS + 1] = { 1, 76, 76 * scanlines, freq, freq * 60, Int64(1) << 62 };
|
||||
|
@ -298,7 +297,7 @@ string RewindManager::getUnitString(Int64 cycles)
|
|||
{
|
||||
// use the lower unit up to twice the nextCycles unit, except for an exact match of the nextCycles unit
|
||||
// TODO: does the latter make sense, e.g. for ROMs with changing scanlines?
|
||||
if(cycles == 0 || cycles < UNIT_CYCLES[i + 1] * 2 && cycles % UNIT_CYCLES[i + 1] != 0)
|
||||
if(cycles == 0 || (cycles < UNIT_CYCLES[i + 1] * 2 && cycles % UNIT_CYCLES[i + 1] != 0))
|
||||
break;
|
||||
}
|
||||
result << cycles / UNIT_CYCLES[i] << " " << UNIT_NAMES[i];
|
||||
|
@ -309,14 +308,13 @@ string RewindManager::getUnitString(Int64 cycles)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 RewindManager::getFirstCycles() const
|
||||
uInt64 RewindManager::getFirstCycles() const
|
||||
{
|
||||
// TODO: check if valid
|
||||
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.first())->cycles;
|
||||
return !myStateList.empty() ? myStateList.first()->cycles : 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 RewindManager::getCurrentCycles() const
|
||||
uInt64 RewindManager::getCurrentCycles() const
|
||||
{
|
||||
if(myStateList.currentIsValid())
|
||||
return myStateList.current().cycles;
|
||||
|
@ -325,10 +323,9 @@ uInt32 RewindManager::getCurrentCycles() const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 RewindManager::getLastCycles() const
|
||||
uInt64 RewindManager::getLastCycles() const
|
||||
{
|
||||
// TODO: check if valid
|
||||
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.last())->cycles;
|
||||
return !myStateList.empty() ? myStateList.last()->cycles : 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -149,9 +149,9 @@ class RewindManager
|
|||
uInt32 getCurrentIdx() { return myStateList.currentIdx(); }
|
||||
uInt32 getLastIdx() { return myStateList.size(); }
|
||||
|
||||
uInt32 getFirstCycles() const;
|
||||
uInt32 getCurrentCycles() const;
|
||||
uInt32 getLastCycles() const;
|
||||
uInt64 getFirstCycles() const;
|
||||
uInt64 getCurrentCycles() const;
|
||||
uInt64 getLastCycles() const;
|
||||
|
||||
/**
|
||||
Get a collection of cycle timestamps, offset from the first one in
|
||||
|
|
|
@ -49,6 +49,15 @@ class FixedStack
|
|||
T pop() { return std::move(_stack[--_size]); }
|
||||
uInt32 size() const { return _size; }
|
||||
|
||||
void replace(const T& oldItem, const T& newItem) {
|
||||
for(uInt32 i = 0; i < _size; ++i) {
|
||||
if(_stack[i] == oldItem) {
|
||||
_stack[i] = newItem;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the given function to every item in the stack
|
||||
// We do it this way so the stack API can be preserved,
|
||||
// and no access to individual elements is allowed outside
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "StateManager.hxx"
|
||||
|
||||
#define STATE_HEADER "05009901state"
|
||||
#define STATE_HEADER "05010000state"
|
||||
// #define MOVIE_HEADER "03030000movie"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef VERSION_HXX
|
||||
#define VERSION_HXX
|
||||
|
||||
#define STELLA_VERSION "5.1_b1"
|
||||
#define STELLA_BUILD "3826"
|
||||
#define STELLA_VERSION "5.1"
|
||||
#define STELLA_BUILD "4138"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -76,6 +76,7 @@ using std::memcpy;
|
|||
|
||||
// Common array types
|
||||
using IntArray = std::vector<Int32>;
|
||||
using uIntArray = std::vector<uInt32>;
|
||||
using BoolArray = std::vector<bool>;
|
||||
using ByteArray = std::vector<uInt8>;
|
||||
using ShortArray = std::vector<uInt16>;
|
||||
|
|
|
@ -301,31 +301,21 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
|||
{
|
||||
case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states
|
||||
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, false);
|
||||
break;
|
||||
return;
|
||||
|
||||
case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states
|
||||
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, true);
|
||||
break;
|
||||
return;
|
||||
|
||||
case KBDK_DOWN: // Alt-down rewinds to start of list
|
||||
enterTimeMachineMenuMode(1000, false);
|
||||
break;
|
||||
return;
|
||||
|
||||
case KBDK_UP: // Alt-up rewinds to end of list
|
||||
enterTimeMachineMenuMode(1000, true);
|
||||
break;
|
||||
return;
|
||||
|
||||
default:
|
||||
handled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// These only work when in emulation mode
|
||||
if(!handled && (myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE))
|
||||
{
|
||||
handled = true;
|
||||
switch(key)
|
||||
{
|
||||
// These can work in pause mode too
|
||||
case KBDK_EQUALS:
|
||||
myOSystem.frameBuffer().changeWindowedVidMode(+1);
|
||||
break;
|
||||
|
@ -390,10 +380,10 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
|||
{
|
||||
if(mod & KBDM_SHIFT)
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().setPreviousAdjustable());
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().setPreviousAdjustable());
|
||||
else
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().setNextAdjustable());
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().setNextAdjustable());
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -402,10 +392,10 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
|||
{
|
||||
if(mod & KBDM_SHIFT)
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().decreaseAdjustable());
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().decreaseAdjustable());
|
||||
else
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().increaseAdjustable());
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().increaseAdjustable());
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -420,7 +410,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
|||
if(mod & KBDM_SHIFT)
|
||||
myOSystem.console().toggleP1Collision();
|
||||
else
|
||||
myOSystem.console().toggleP1Bit();
|
||||
myOSystem.console().toggleP1Bit();
|
||||
break;
|
||||
|
||||
case KBDK_C:
|
||||
|
@ -508,8 +498,8 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
|||
{
|
||||
ostringstream buf;
|
||||
buf << "Disabling snapshots, generated "
|
||||
<< (myContSnapshotCounter / myContSnapshotInterval)
|
||||
<< " files";
|
||||
<< (myContSnapshotCounter / myContSnapshotInterval)
|
||||
<< " files";
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
setContinuousSnapshots(0);
|
||||
}
|
||||
|
@ -2161,6 +2151,11 @@ void EventHandler::enterTimeMachineMenuMode(uInt32 numWinds, bool unwind)
|
|||
// add one extra state if we are in Time Machine mode
|
||||
// TODO: maybe remove this state if we leave the menu at this new state
|
||||
myOSystem.state().addExtraState("enter Time Machine dialog"); // force new state
|
||||
if(numWinds)
|
||||
myOSystem.state().windStates(numWinds, unwind);
|
||||
|
||||
if(numWinds)
|
||||
myOSystem.state().windStates(numWinds, unwind);
|
||||
|
||||
// TODO: display last wind message (numWinds != 0) in time machine dialog
|
||||
enterMenuMode(EventHandlerState::TIMEMACHINE);
|
||||
|
@ -2204,6 +2199,7 @@ void EventHandler::setEventState(EventHandlerState state)
|
|||
break;
|
||||
|
||||
case EventHandlerState::TIMEMACHINE:
|
||||
myOSystem.timeMachine().requestResize();
|
||||
myOverlay = &myOSystem.timeMachine();
|
||||
enableTextEvents(true);
|
||||
break;
|
||||
|
|
|
@ -147,7 +147,6 @@ bool FrameBuffer::initialize()
|
|||
FBSurface::setPalette(myPalette);
|
||||
|
||||
myGrabMouse = myOSystem.settings().getBool("grabmouse");
|
||||
myZoomMode = myOSystem.settings().getInt("tia.zoom");
|
||||
|
||||
// Create a TIA surface; we need it for rendering TIA images
|
||||
myTIASurface = make_unique<TIASurface>(myOSystem);
|
||||
|
@ -235,7 +234,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
|
|||
{
|
||||
myStatsMsg.surface = allocateSurface(myStatsMsg.w, myStatsMsg.h);
|
||||
myStatsMsg.surface->attributes().blending = true;
|
||||
//myStatsMsg.surface->attributes().blendalpha = 80;
|
||||
myStatsMsg.surface->attributes().blendalpha = 92; //aligned with TimeMachineDialog
|
||||
myStatsMsg.surface->applyAttributes();
|
||||
}
|
||||
|
||||
|
@ -387,9 +386,10 @@ void FrameBuffer::drawFrameStats()
|
|||
|
||||
myStatsMsg.surface->invalidate();
|
||||
string bsinfo = info.BankSwitch +
|
||||
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player");
|
||||
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "");
|
||||
// draw shadowed text
|
||||
color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ? kDbgColorRed : myStatsMsg.color;
|
||||
color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ?
|
||||
uInt32(kDbgColorRed) : myStatsMsg.color;
|
||||
std::snprintf(msg, 30, "%3u", myOSystem.console().tia().scanlinesLastFrame());
|
||||
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
||||
myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
@ -404,13 +404,13 @@ void FrameBuffer::drawFrameStats()
|
|||
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
// draw bankswitching type
|
||||
myStatsMsg.surface->drawString(font(), bsinfo, XPOS, YPOS + font().getFontHeight(),
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
myStatsMsg.surface->setDirty();
|
||||
myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1);
|
||||
myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8);
|
||||
myStatsMsg.surface->render();
|
||||
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -631,7 +631,7 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
|
|||
|
||||
resetSurfaces();
|
||||
showMessage(mode.description);
|
||||
myZoomMode = mode.zoom;
|
||||
myOSystem.settings().setValue("tia.zoom", mode.zoom);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -789,17 +789,11 @@ const VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
|
|||
if(state == EventHandlerState::DEBUGGER || state == EventHandlerState::LAUNCHER)
|
||||
myCurrentModeList->setZoom(1);
|
||||
else
|
||||
myCurrentModeList->setZoom(myZoomMode);
|
||||
myCurrentModeList->setZoom(myOSystem.settings().getInt("tia.zoom"));
|
||||
|
||||
return myCurrentModeList->current();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::setZoomMode(uInt32 mode)
|
||||
{
|
||||
myZoomMode = mode;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//
|
||||
// VideoMode implementation
|
||||
|
@ -984,11 +978,11 @@ void FrameBuffer::VideoModeList::setZoom(uInt32 zoom)
|
|||
kScrollColor Normal scrollbar color
|
||||
kScrollColorHi Highlighted scrollbar color
|
||||
*** Slider colors ***
|
||||
kSliderColor,
|
||||
kSliderColorHi
|
||||
kSliderBGColor
|
||||
kSliderBGColorHi
|
||||
kSliderBGColorLo,
|
||||
kSliderColor Enabled slider
|
||||
kSliderColorHi Focussed slider
|
||||
kSliderBGColor Enabled slider background
|
||||
kSliderBGColorHi Focussed slider background
|
||||
kSliderBGColorLo Disabled slider background
|
||||
*** Debugger colors ***
|
||||
kDbgChangedColor Background color for changed cells
|
||||
kDbgChangedTextColor Text color for changed cells
|
||||
|
@ -1031,7 +1025,7 @@ uInt32 FrameBuffer::ourGUIColors[3][kNumColors-256] = {
|
|||
0xe1e1e1, 0xe5f1fb, 0x808080, 0x0078d7, 0x000000, 0x000000, // buttons
|
||||
0x333333, // checkbox
|
||||
0xc0c0c0, 0x808080, // scrollbar
|
||||
0x333333, 0x0078d7, 0xc0c0c0, 0x808080, 0xe1e1e1, // slider
|
||||
0x333333, 0x0078d7, 0xc0c0c0, 0xffffff, 0xc0c0c0, // slider 0xBDDEF9| 0xe1e1e1 | 0xffffff
|
||||
0xffc0c0, 0x000000, 0xe00000, 0xc00000, // debugger
|
||||
0xffffff, 0x333333, 0xf0f0f0, 0x808080, 0xc0c0c0 // other
|
||||
}
|
||||
|
|
|
@ -193,11 +193,6 @@ class FrameBuffer
|
|||
*/
|
||||
const VariantList& supportedTIAZoomLevels() const { return myTIAZoomLevels; }
|
||||
|
||||
/*
|
||||
Set the current zoom mode.
|
||||
*/
|
||||
void setZoomMode(uInt32 mode);
|
||||
|
||||
/**
|
||||
Get the font object(s) of the framebuffer
|
||||
*/
|
||||
|
@ -528,9 +523,6 @@ class FrameBuffer
|
|||
// Names of the TIA zoom levels that can be used for this framebuffer
|
||||
VariantList myTIAZoomLevels;
|
||||
|
||||
// curently selected zoom mode
|
||||
uInt32 myZoomMode;
|
||||
|
||||
// Holds a reference to all the surfaces that have been created
|
||||
vector<shared_ptr<FBSurface>> mySurfaceList;
|
||||
|
||||
|
|
|
@ -1231,6 +1231,8 @@ void TIA::tickHblank()
|
|||
if (myExtendedHblank) myHstate = HState::frame;
|
||||
break;
|
||||
}
|
||||
|
||||
if (myExtendedHblank && myHctr > 67) myPlayfield.tick(myHctr - 68 - myHctrDelta);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1271,6 +1273,7 @@ void TIA::nextLine()
|
|||
cloneLastLine();
|
||||
}
|
||||
|
||||
myPlayfield.tick(0);
|
||||
myHctr = 0;
|
||||
|
||||
if (!myMovementInProgress && myLinesSinceChange < 2) myLinesSinceChange++;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
ConfigPathDialog::ConfigPathDialog(
|
||||
OSystem& osystem, DialogContainer& parent,
|
||||
const GUI::Font& font, GuiObject* boss)
|
||||
const GUI::Font& font, GuiObject* boss, int max_w, int max_h)
|
||||
: Dialog(osystem, parent, font, "Configure paths"),
|
||||
CommandSender(boss),
|
||||
myFont(font),
|
||||
|
@ -48,7 +48,7 @@ ConfigPathDialog::ConfigPathDialog(
|
|||
ButtonWidget* b;
|
||||
|
||||
// Set real dimensions
|
||||
_w = 64 * fontWidth + HBORDER*2;
|
||||
_w = std::min(64 * fontWidth + HBORDER*2, max_w);
|
||||
_h = 9 * (lineHeight + V_GAP) + VBORDER;
|
||||
|
||||
xpos = HBORDER; ypos = VBORDER;
|
||||
|
|
|
@ -35,7 +35,7 @@ class ConfigPathDialog : public Dialog, public CommandSender
|
|||
{
|
||||
public:
|
||||
ConfigPathDialog(OSystem& osystem, DialogContainer& parent,
|
||||
const GUI::Font& font, GuiObject* boss);
|
||||
const GUI::Font& font, GuiObject* boss, int max_w, int max_h);
|
||||
virtual ~ConfigPathDialog();
|
||||
|
||||
private:
|
||||
|
|
|
@ -205,6 +205,7 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font)
|
|||
myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1,
|
||||
"Recovery ", 0, kTVJitterChanged);
|
||||
myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20);
|
||||
myTVJitterRecWidget->setTickmarkInterval(5);
|
||||
wid.push_back(myTVJitterRecWidget);
|
||||
myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font,
|
||||
myTVJitterRecWidget->getRight() + 4,
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "ContextMenu.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "Console.hxx"
|
||||
|
||||
#include "Vec.hxx"
|
||||
|
||||
|
@ -813,16 +815,20 @@ Widget* Dialog::TabFocus::getNewFocus()
|
|||
bool Dialog::getResizableBounds(uInt32& w, uInt32& h) const
|
||||
{
|
||||
const GUI::Rect& r = instance().frameBuffer().imageRect();
|
||||
|
||||
bool ntsc = instance().console().about().InitialFrameRate == "60";
|
||||
uInt32 aspect = instance().settings().getInt(ntsc ?"tia.aspectn" : "tia.aspectp");
|
||||
|
||||
if(r.width() <= FrameBuffer::kFBMinW || r.height() <= FrameBuffer::kFBMinH)
|
||||
{
|
||||
w = uInt32(0.8 * FrameBuffer::kTIAMinW) * 2;
|
||||
w = uInt32(aspect * FrameBuffer::kTIAMinW) * 2 / 100;
|
||||
h = FrameBuffer::kTIAMinH * 2;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = std::max(uInt32(0.8 * r.width()), uInt32(FrameBuffer::kFBMinW));
|
||||
h = std::max(uInt32(0.8 * r.height()), uInt32(FrameBuffer::kFBMinH));
|
||||
w = std::max(uInt32(aspect * r.width() / 100), uInt32(FrameBuffer::kFBMinW));
|
||||
h = std::max(uInt32(aspect * r.height() / 100), uInt32(FrameBuffer::kFBMinH));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,10 +75,11 @@ class Dialog : public GuiObject
|
|||
/** Returns the base surface associated with this dialog. */
|
||||
FBSurface& surface() const { return *_surface; }
|
||||
|
||||
/** Adds a surface to this dialog, which is rendered on top of the
|
||||
base surface whenever the base surface is re-rendered. Since
|
||||
the surface render() call will always occur in such a case, the
|
||||
surface should call setVisible() to enable/disable its output.
|
||||
/**
|
||||
Adds a surface to this dialog, which is rendered on top of the
|
||||
base surface whenever the base surface is re-rendered. Since
|
||||
the surface render() call will always occur in such a case, the
|
||||
surface should call setVisible() to enable/disable its output.
|
||||
*/
|
||||
void addSurface(shared_ptr<FBSurface> surface);
|
||||
|
||||
|
@ -89,6 +90,11 @@ class Dialog : public GuiObject
|
|||
void setTitle(const string& title);
|
||||
bool hasTitle() { return !_title.empty(); }
|
||||
|
||||
/** Determine the maximum bounds based on the given width and height
|
||||
Returns whether or not a large font can be used within these bounds.
|
||||
*/
|
||||
bool getResizableBounds(uInt32& w, uInt32& h) const;
|
||||
|
||||
protected:
|
||||
virtual void draw() override { }
|
||||
void releaseFocus() override;
|
||||
|
@ -123,11 +129,6 @@ class Dialog : public GuiObject
|
|||
|
||||
void processCancelWithoutWidget(bool state) { _processCancel = state; }
|
||||
|
||||
/** Determine the maximum bounds based on the given width and height
|
||||
Returns whether or not a large font can be used within these bounds.
|
||||
*/
|
||||
bool getResizableBounds(uInt32& w, uInt32& h) const;
|
||||
|
||||
void initTitle(const GUI::Font& font, const string& title);
|
||||
|
||||
private:
|
||||
|
|
|
@ -119,7 +119,7 @@ void DialogContainer::addDialog(Dialog* d)
|
|||
const GUI::Rect& r = myOSystem.frameBuffer().imageRect();
|
||||
if(uInt32(d->getWidth()) > r.width() || uInt32(d->getHeight()) > r.height())
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
"Unable to show dialog box; resize current window");
|
||||
"Unable to show dialog box; FIX THE CODE");
|
||||
else
|
||||
myDialogStack.push(d);
|
||||
}
|
||||
|
|
|
@ -134,6 +134,14 @@ class DialogContainer
|
|||
*/
|
||||
const Dialog* baseDialog() const { return myBaseDialog; }
|
||||
|
||||
/**
|
||||
Inform the container that it should resize according to the current
|
||||
screen dimensions. We make this virtual, since the container may or
|
||||
may not choose to do a resize, and even if it does, *how* it does it
|
||||
is determined by the specific container.
|
||||
*/
|
||||
virtual void requestResize() { }
|
||||
|
||||
private:
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "AboutDialog.hxx"
|
||||
#include "OptionsDialog.hxx"
|
||||
#include "Launcher.hxx"
|
||||
#include "Settings.hxx"
|
||||
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
#include "CheatCodeDialog.hxx"
|
||||
|
@ -48,7 +49,8 @@
|
|||
OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
|
||||
GuiObject* boss, int max_w, int max_h, stellaMode mode)
|
||||
: Dialog(osystem, parent),
|
||||
myMode(mode)
|
||||
myMode(mode),
|
||||
_boss(boss)
|
||||
{
|
||||
const GUI::Font& font = instance().frameBuffer().font();
|
||||
initTitle(font, "Options");
|
||||
|
@ -97,7 +99,6 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
|
|||
b = ADD_OD_BUTTON("Developer" + ELLIPSIS, kDevelopCmd);
|
||||
wid.push_back(b);
|
||||
|
||||
|
||||
// Move to second column
|
||||
xoffset += buttonWidth + 10; yoffset = VBORDER;
|
||||
|
||||
|
@ -131,8 +132,8 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
|
|||
myAudioDialog = make_unique<AudioDialog>(osystem, parent, font);
|
||||
myInputDialog = make_unique<InputDialog>(osystem, parent, font, max_w, max_h);
|
||||
myUIDialog = make_unique<UIDialog>(osystem, parent, font);
|
||||
mySnapshotDialog = make_unique<SnapshotDialog>(osystem, parent, font);
|
||||
myConfigPathDialog = make_unique<ConfigPathDialog>(osystem, parent, font, boss);
|
||||
mySnapshotDialog = make_unique<SnapshotDialog>(osystem, parent, font, max_w, max_h);
|
||||
myConfigPathDialog = make_unique<ConfigPathDialog>(osystem, parent, font, boss, max_w, max_h);
|
||||
myRomAuditDialog = make_unique<RomAuditDialog>(osystem, parent, font, max_w, max_h);
|
||||
myGameInfoDialog = make_unique<GameInfoDialog>(osystem, parent, font, this);
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
|
@ -190,6 +191,15 @@ void OptionsDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
switch(cmd)
|
||||
{
|
||||
case kVidCmd:
|
||||
// This dialog is resizable under certain conditions, so we need
|
||||
// to re-create it as necessary
|
||||
if(myMode != launcher)
|
||||
{
|
||||
uInt32 w = 0, h = 0;
|
||||
|
||||
getResizableBounds(w, h);
|
||||
myVideoDialog = make_unique<VideoDialog>(instance(), parent(), instance().frameBuffer().font(), w, h);
|
||||
}
|
||||
myVideoDialog->open();
|
||||
break;
|
||||
|
||||
|
@ -206,10 +216,29 @@ void OptionsDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
break;
|
||||
|
||||
case kSnapCmd:
|
||||
// This dialog is resizable under certain conditions, so we need
|
||||
// to re-create it as necessary
|
||||
if(myMode != launcher)
|
||||
{
|
||||
uInt32 w = 0, h = 0;
|
||||
|
||||
getResizableBounds(w, h);
|
||||
mySnapshotDialog = make_unique<SnapshotDialog>(instance(), parent(), instance().frameBuffer().font(), w, h);
|
||||
}
|
||||
mySnapshotDialog->open();
|
||||
break;
|
||||
|
||||
case kCfgPathsCmd:
|
||||
// This dialog is resizable under certain conditions, so we need
|
||||
// to re-create it as necessary
|
||||
if(myMode != launcher)
|
||||
{
|
||||
uInt32 w = 0, h = 0;
|
||||
|
||||
getResizableBounds(w, h);
|
||||
myConfigPathDialog = make_unique<ConfigPathDialog>(instance(), parent(),
|
||||
instance().frameBuffer().font(), _boss, w, h);
|
||||
}
|
||||
myConfigPathDialog->open();
|
||||
break;
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@ class OptionsDialog : public Dialog
|
|||
// Indicates if this dialog is used for global (vs. in-game) settings
|
||||
stellaMode myMode;
|
||||
|
||||
GuiObject* _boss;
|
||||
|
||||
enum {
|
||||
kVidCmd = 'VIDO',
|
||||
kAudCmd = 'AUDO',
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent,
|
||||
const GUI::Font& font)
|
||||
const GUI::Font& font, int max_w, int max_h)
|
||||
: Dialog(osystem, parent, font, "Snapshot settings"),
|
||||
myFont(font)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent,
|
|||
ButtonWidget* b;
|
||||
|
||||
// Set real dimensions
|
||||
_w = 64 * fontWidth + HBORDER * 2;
|
||||
_w = std::min(max_w, 64 * fontWidth + HBORDER * 2);
|
||||
_h = 10 * (lineHeight + 4) + VBORDER + _th;
|
||||
|
||||
xpos = HBORDER; ypos = VBORDER + _th;
|
||||
|
|
|
@ -34,7 +34,7 @@ class SnapshotDialog : public Dialog
|
|||
{
|
||||
public:
|
||||
SnapshotDialog(OSystem& osystem, DialogContainer& parent,
|
||||
const GUI::Font& font);
|
||||
const GUI::Font& font, int max_w, int max_h);
|
||||
virtual ~SnapshotDialog();
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,18 +25,14 @@
|
|||
|
||||
#include "TimeLineWidget.hxx"
|
||||
|
||||
// TODO - remove all references to _stepValue__
|
||||
// - fix posToValue to use _stepValue
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int w, int h,
|
||||
const string& label, int labelWidth, int cmd)
|
||||
const string& label, uInt32 labelWidth, int cmd)
|
||||
: ButtonWidget(boss, font, x, y, w, h, label, cmd),
|
||||
_value(0),
|
||||
_stepValue__(1),
|
||||
_valueMin(0),
|
||||
_valueMax(100),
|
||||
_valueMax(0),
|
||||
_isDragging(false),
|
||||
_labelWidth(labelWidth)
|
||||
{
|
||||
|
@ -53,10 +49,9 @@ TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeLineWidget::setValue(int value)
|
||||
void TimeLineWidget::setValue(uInt32 value)
|
||||
{
|
||||
if(value < _valueMin) value = _valueMin;
|
||||
else if(value > _valueMax) value = _valueMax;
|
||||
value = BSPF::clamp(value, _valueMin, _valueMax);
|
||||
|
||||
if(value != _value)
|
||||
{
|
||||
|
@ -67,13 +62,13 @@ void TimeLineWidget::setValue(int value)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeLineWidget::setMinValue(int value)
|
||||
void TimeLineWidget::setMinValue(uInt32 value)
|
||||
{
|
||||
_valueMin = value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeLineWidget::setMaxValue(int value)
|
||||
void TimeLineWidget::setMaxValue(uInt32 value)
|
||||
{
|
||||
_valueMax = value;
|
||||
}
|
||||
|
@ -81,27 +76,32 @@ void TimeLineWidget::setMaxValue(int value)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeLineWidget::setStepValues(const IntArray& steps)
|
||||
{
|
||||
// Try to allocate as infrequently as possible
|
||||
if(steps.size() > _stepValue.capacity())
|
||||
_stepValue.reserve(2 * steps.size());
|
||||
_stepValue.clear();
|
||||
|
||||
double scale = (_w - _labelWidth - 4) / double(steps.back());
|
||||
// If no steps are defined, just use the maximum value
|
||||
if(steps.size() > 0)
|
||||
{
|
||||
// Try to allocate as infrequently as possible
|
||||
if(steps.size() > _stepValue.capacity())
|
||||
_stepValue.reserve(2 * steps.size());
|
||||
|
||||
// Skip the very last value; we take care of it outside the end of the loop
|
||||
for(uInt32 i = 0; i < steps.size() - 1; ++i)
|
||||
_stepValue.push_back(int(steps[i] * scale));
|
||||
double scale = (_w - _labelWidth - 2) / double(steps.back());
|
||||
|
||||
// Due to integer <-> double conversion, the last value is sometimes
|
||||
// slightly less than the maximum value; we assign it manually to fix this
|
||||
_stepValue.push_back(_w - _labelWidth - 4);
|
||||
// Skip the very last value; we take care of it outside the end of the loop
|
||||
for(uInt32 i = 0; i < steps.size() - 1; ++i)
|
||||
_stepValue.push_back(int(steps[i] * scale));
|
||||
|
||||
// Due to integer <-> double conversion, the last value is sometimes
|
||||
// slightly less than the maximum value; we assign it manually to fix this
|
||||
_stepValue.push_back(_w - _labelWidth - 2);
|
||||
}
|
||||
else
|
||||
_stepValue.push_back(0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeLineWidget::handleMouseMoved(int x, int y)
|
||||
{
|
||||
// TODO: when the mouse is dragged outside the widget, the slider should
|
||||
// snap back to the old value.
|
||||
if(isEnabled() && _isDragging && x >= int(_labelWidth))
|
||||
setValue(posToValue(x - _labelWidth));
|
||||
}
|
||||
|
@ -130,47 +130,13 @@ void TimeLineWidget::handleMouseWheel(int x, int y, int direction)
|
|||
{
|
||||
if(isEnabled())
|
||||
{
|
||||
if(direction < 0)
|
||||
handleEvent(Event::UIUp);
|
||||
else if(direction > 0)
|
||||
handleEvent(Event::UIDown);
|
||||
if(direction < 0 && _value < _valueMax)
|
||||
setValue(_value + 1);
|
||||
else if(direction > 0 && _value > _valueMin)
|
||||
setValue(_value - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool TimeLineWidget::handleEvent(Event::Type e)
|
||||
{
|
||||
if(!isEnabled())
|
||||
return false;
|
||||
|
||||
switch(e)
|
||||
{
|
||||
case Event::UIDown:
|
||||
case Event::UILeft:
|
||||
case Event::UIPgDown:
|
||||
setValue(_value - _stepValue__);
|
||||
break;
|
||||
|
||||
case Event::UIUp:
|
||||
case Event::UIRight:
|
||||
case Event::UIPgUp:
|
||||
setValue(_value + _stepValue__);
|
||||
break;
|
||||
|
||||
case Event::UIHome:
|
||||
setValue(_valueMin);
|
||||
break;
|
||||
|
||||
case Event::UIEnd:
|
||||
setValue(_valueMax);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeLineWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
@ -183,13 +149,26 @@ void TimeLineWidget::drawWidget(bool hilite)
|
|||
isEnabled() ? kTextColor : kColor, TextAlign::Right);
|
||||
|
||||
// Draw the box
|
||||
s.box(_x + _labelWidth, _y, _w - _labelWidth, _h, kColor, kShadowColor);
|
||||
s.frameRect(_x + _labelWidth, _y, _w - _labelWidth, _h, kColor);
|
||||
// Fill the box
|
||||
s.fillRect(_x + _labelWidth + 2, _y + 2, _w - _labelWidth - 4, _h - 4,
|
||||
s.fillRect(_x + _labelWidth + 1, _y + 1, _w - _labelWidth - 2, _h - 2,
|
||||
!isEnabled() ? kBGColorHi : kWidColor);
|
||||
// Draw the 'bar'
|
||||
s.fillRect(_x + _labelWidth + 2, _y + 2, valueToPos(_value), _h - 4,
|
||||
int vp = valueToPos(_value);
|
||||
s.fillRect(_x + _labelWidth + 1, _y + 1, vp, _h - 2,
|
||||
!isEnabled() ? kColor : hilite ? kSliderColorHi : kSliderColor);
|
||||
|
||||
// add 4 tickmarks for 5 intervals
|
||||
int numTicks = std::min(5, int(_stepValue.size()));
|
||||
for(int i = 1; i < numTicks; ++i)
|
||||
{
|
||||
int idx = int((_stepValue.size() * i + numTicks / 2) / numTicks);
|
||||
if(idx > 1)
|
||||
{
|
||||
int tp = valueToPos(idx - 1);
|
||||
s.vLine(_x + _labelWidth + tp, _y + _h / 2, _y + _h - 2, tp > vp ? kSliderColor : kWidColor);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Draw the label, if any
|
||||
if(_labelWidth > 0)
|
||||
|
@ -208,25 +187,19 @@ void TimeLineWidget::drawWidget(bool hilite)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int TimeLineWidget::valueToPos(int value)
|
||||
uInt32 TimeLineWidget::valueToPos(uInt32 value)
|
||||
{
|
||||
if(value < _valueMin) value = _valueMin;
|
||||
else if(value > _valueMax) value = _valueMax;
|
||||
|
||||
int real = _stepValue[BSPF::clamp(value, _valueMin, _valueMax)];
|
||||
#if 0
|
||||
int range = std::max(_valueMax - _valueMin, 1); // don't divide by zero
|
||||
int actual = ((_w - _labelWidth - 4) * (value - _valueMin) / range);
|
||||
cerr << "i=" << value << " real=" << real << endl << "actual=" << actual << endl << endl;
|
||||
#endif
|
||||
return real;
|
||||
return _stepValue[BSPF::clamp(value, _valueMin, _valueMax)];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int TimeLineWidget::posToValue(int pos)
|
||||
uInt32 TimeLineWidget::posToValue(uInt32 pos)
|
||||
{
|
||||
int value = (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin;
|
||||
// Find the interval in which 'pos' falls, and then the endpoint which
|
||||
// it is closest to
|
||||
for(uInt32 i = 0; i < _stepValue.size() - 1; ++i)
|
||||
if(pos >= _stepValue[i] && pos <= _stepValue[i+1])
|
||||
return (_stepValue[i+1] - pos) < (pos - _stepValue[i]) ? i+1 : i;
|
||||
|
||||
// Scale the position to the correct interval (according to step value)
|
||||
return value - (value % _stepValue__);
|
||||
return _valueMax;
|
||||
}
|
||||
|
|
|
@ -25,15 +25,15 @@ class TimeLineWidget : public ButtonWidget
|
|||
public:
|
||||
TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int w, int h, const string& label = "",
|
||||
int labelWidth = 0, int cmd = 0);
|
||||
uInt32 labelWidth = 0, int cmd = 0);
|
||||
|
||||
void setValue(int value);
|
||||
int getValue() const { return _value; }
|
||||
void setValue(uInt32 value);
|
||||
uInt32 getValue() const { return _value; }
|
||||
|
||||
void setMinValue(int value);
|
||||
int getMinValue() const { return _valueMin; }
|
||||
void setMaxValue(int value);
|
||||
int getMaxValue() const { return _valueMax; }
|
||||
void setMinValue(uInt32 value);
|
||||
void setMaxValue(uInt32 value);
|
||||
uInt32 getMinValue() const { return _valueMin; }
|
||||
uInt32 getMaxValue() const { return _valueMax; }
|
||||
|
||||
/**
|
||||
Steps are not necessarily linear in a timeline, so we need info
|
||||
|
@ -46,20 +46,19 @@ class TimeLineWidget : public ButtonWidget
|
|||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseWheel(int x, int y, int direction) override;
|
||||
bool handleEvent(Event::Type event) override;
|
||||
|
||||
void drawWidget(bool hilite) override;
|
||||
|
||||
int valueToPos(int value);
|
||||
int posToValue(int pos);
|
||||
uInt32 valueToPos(uInt32 value);
|
||||
uInt32 posToValue(uInt32 pos);
|
||||
|
||||
protected:
|
||||
int _value, _stepValue__;
|
||||
int _valueMin, _valueMax;
|
||||
bool _isDragging;
|
||||
int _labelWidth;
|
||||
uInt32 _value;
|
||||
uInt32 _valueMin, _valueMax;
|
||||
bool _isDragging;
|
||||
uInt32 _labelWidth;
|
||||
|
||||
IntArray _stepValue;
|
||||
uIntArray _stepValue;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -22,8 +22,37 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TimeMachine::TimeMachine(OSystem& osystem)
|
||||
: DialogContainer(osystem)
|
||||
: DialogContainer(osystem),
|
||||
myWidth(FrameBuffer::kFBMinW)
|
||||
{
|
||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this,
|
||||
FrameBuffer::kFBMinW, FrameBuffer::kFBMinH);
|
||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this, myWidth);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeMachine::requestResize()
|
||||
{
|
||||
uInt32 w, h;
|
||||
myBaseDialog->getResizableBounds(w, h);
|
||||
|
||||
// If dialog is too large for given area, we need to resize it
|
||||
// Otherwise, make it 80% of the allowable width
|
||||
int newWidth = myWidth;
|
||||
if(w < FrameBuffer::kFBMinW)
|
||||
newWidth = w;
|
||||
else if(myBaseDialog->getWidth() != 0.8 * w)
|
||||
newWidth = uInt32(0.8 * w);
|
||||
|
||||
// Only re-create when absolutely necessary
|
||||
if(myWidth != newWidth)
|
||||
{
|
||||
myWidth = newWidth;
|
||||
Dialog* oldPtr = myBaseDialog;
|
||||
delete myBaseDialog;
|
||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this, myWidth);
|
||||
Dialog* newPtr = myBaseDialog;
|
||||
|
||||
// Update the container stack; it may contain a reference to the old pointer
|
||||
if(oldPtr != newPtr)
|
||||
myDialogStack.replace(oldPtr, newPtr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,15 @@ class TimeMachine : public DialogContainer
|
|||
TimeMachine(OSystem& osystem);
|
||||
virtual ~TimeMachine() = default;
|
||||
|
||||
/**
|
||||
This dialog has an adjustable size. We need to make sure the
|
||||
dialog can fit within the given bounds.
|
||||
*/
|
||||
void requestResize() override;
|
||||
|
||||
private:
|
||||
int myWidth;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
TimeMachine() = delete;
|
||||
|
|
|
@ -36,7 +36,7 @@ using Common::Base;
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||
int max_w, int max_h)
|
||||
int width)
|
||||
: Dialog(osystem, parent)
|
||||
{
|
||||
const int BUTTON_W = 16, BUTTON_H = 14;
|
||||
|
@ -75,23 +75,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
0b0110000110000110,
|
||||
0
|
||||
};
|
||||
static uInt32 REWIND_10[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b0000010000100110,
|
||||
0b0000110001100110,
|
||||
0b0001110011100110,
|
||||
0b0011110111100110,
|
||||
0b0111111111100110,
|
||||
0b1111111111100110,
|
||||
0b1111111111100110,
|
||||
0b0111111111100110,
|
||||
0b0011110111100110,
|
||||
0b0001110011100110,
|
||||
0b0000110001100110,
|
||||
0b0000010000100110,
|
||||
0
|
||||
};
|
||||
static uInt32 REWIND_1[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
|
@ -126,23 +109,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
0b0011100011000000,
|
||||
0
|
||||
};
|
||||
static uInt32 UNWIND_10[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b0110010000100000,
|
||||
0b0110011000110000,
|
||||
0b0110011100111000,
|
||||
0b0110011110111100,
|
||||
0b0110011111111110,
|
||||
0b0110011111111111,
|
||||
0b0110011111111111,
|
||||
0b0110011111111110,
|
||||
0b0110011110111100,
|
||||
0b0110011100111000,
|
||||
0b0110011000110000,
|
||||
0b0110010000100000,
|
||||
0
|
||||
};
|
||||
static uInt32 UNWIND_ALL[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
|
@ -170,7 +136,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
int xpos, ypos;
|
||||
|
||||
// Set real dimensions
|
||||
_w = 20 * (buttonWidth + BUTTON_GAP) + 20;
|
||||
_w = width; // Parent determines our width (based on window size)
|
||||
_h = V_BORDER * 2 + rowHeight + buttonHeight + 2;
|
||||
|
||||
this->clearFlags(WIDGET_CLEARBG); // does only work combined with blending (0..100)!
|
||||
|
@ -189,7 +155,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
// Add timeline
|
||||
const uInt32 tl_h = myCurrentIdxWidget->getHeight() / 2,
|
||||
tl_x = xpos + myCurrentIdxWidget->getWidth() + 8,
|
||||
tl_y = ypos + (myCurrentIdxWidget->getHeight() - tl_h) / 2,
|
||||
tl_y = ypos + (myCurrentIdxWidget->getHeight() - tl_h) / 2 - 1,
|
||||
tl_w = myLastIdxWidget->getAbsX() - tl_x - 8;
|
||||
myTimeline = new TimeLineWidget(this, font, tl_x, tl_y, tl_w, tl_h, "", 0, kTimeline);
|
||||
myTimeline->setMinValue(0);
|
||||
|
@ -208,10 +174,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
BUTTON_W, BUTTON_H, kRewindAll);
|
||||
xpos += buttonWidth + BUTTON_GAP;
|
||||
|
||||
myRewind10Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_10,
|
||||
BUTTON_W, BUTTON_H, kRewind10);
|
||||
xpos += buttonWidth + BUTTON_GAP;
|
||||
|
||||
myRewind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_1,
|
||||
BUTTON_W, BUTTON_H, kRewind1);
|
||||
xpos += buttonWidth + BUTTON_GAP*2;
|
||||
|
@ -224,10 +186,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
BUTTON_W, BUTTON_H, kUnwind1);
|
||||
xpos += buttonWidth + BUTTON_GAP;
|
||||
|
||||
myUnwind10Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_10,
|
||||
BUTTON_W, BUTTON_H, kUnwind10);
|
||||
xpos += buttonWidth + BUTTON_GAP;
|
||||
|
||||
myUnwindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_ALL,
|
||||
BUTTON_W, BUTTON_H, kUnwindAll);
|
||||
xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3;
|
||||
|
@ -254,14 +212,15 @@ void TimeMachineDialog::loadConfig()
|
|||
IntArray cycles = r.cyclesList();
|
||||
|
||||
// Set range and intervals for timeline
|
||||
myTimeline->setMaxValue(cycles.size() - 1);
|
||||
uInt32 maxValue = cycles.size() > 1 ? uInt32(cycles.size() - 1) : 0;
|
||||
myTimeline->setMaxValue(maxValue);
|
||||
myTimeline->setStepValues(cycles);
|
||||
|
||||
// Enable blending (only once is necessary)
|
||||
if(!surface().attributes().blending)
|
||||
{
|
||||
surface().attributes().blending = true;
|
||||
surface().attributes().blendalpha = 80;
|
||||
surface().attributes().blendalpha = 92;
|
||||
surface().applyAttributes();
|
||||
}
|
||||
|
||||
|
@ -361,11 +320,11 @@ string TimeMachineDialog::getTimeString(uInt64 cycles)
|
|||
const Int32 PAL_FREQ = 1182298; // ~76*312*50
|
||||
const Int32 freq = isNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second
|
||||
|
||||
uInt32 minutes = cycles / (freq * 60);
|
||||
uInt32 minutes = uInt32(cycles / (freq * 60));
|
||||
cycles -= minutes * (freq * 60);
|
||||
uInt32 seconds = cycles / freq;
|
||||
uInt32 seconds = uInt32(cycles / freq);
|
||||
cycles -= seconds * freq;
|
||||
uInt32 frames = cycles / (scanlines * 76);
|
||||
uInt32 frames = uInt32(cycles / (scanlines * 76));
|
||||
|
||||
stringstream time;
|
||||
time << Common::Base::toString(minutes, Common::Base::F_10_02) << ":";
|
||||
|
@ -395,6 +354,7 @@ void TimeMachineDialog::handleWinds(Int32 numWinds)
|
|||
myMessageWidget->setLabel((numWinds < 0 ? "(-" : "(+") + message + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// Update time
|
||||
myCurrentTimeWidget->setLabel(getTimeString(r.getCurrentCycles() - r.getFirstCycles()));
|
||||
myLastTimeWidget->setLabel(getTimeString(r.getLastCycles() - r.getFirstCycles()));
|
||||
|
@ -404,9 +364,7 @@ void TimeMachineDialog::handleWinds(Int32 numWinds)
|
|||
myLastIdxWidget->setValue(r.getLastIdx());
|
||||
// Enable/disable buttons
|
||||
myRewindAllWidget->setEnabled(!r.atFirst());
|
||||
myRewind10Widget->setEnabled(!r.atFirst());
|
||||
myRewind1Widget->setEnabled(!r.atFirst());
|
||||
myUnwindAllWidget->setEnabled(!r.atLast());
|
||||
myUnwind10Widget->setEnabled(!r.atLast());
|
||||
myUnwind1Widget->setEnabled(!r.atLast());
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class TimeLineWidget;
|
|||
class TimeMachineDialog : public Dialog
|
||||
{
|
||||
public:
|
||||
TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int max_w, int max_h);
|
||||
TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int width);
|
||||
virtual ~TimeMachineDialog() = default;
|
||||
|
||||
private:
|
||||
|
@ -61,10 +61,8 @@ class TimeMachineDialog : public Dialog
|
|||
|
||||
ButtonWidget* myPlayWidget;
|
||||
ButtonWidget* myRewindAllWidget;
|
||||
ButtonWidget* myRewind10Widget;
|
||||
ButtonWidget* myRewind1Widget;
|
||||
ButtonWidget* myUnwind1Widget;
|
||||
ButtonWidget* myUnwind10Widget;
|
||||
ButtonWidget* myUnwindAllWidget;
|
||||
|
||||
StaticTextWidget* myCurrentTimeWidget;
|
||||
|
|
|
@ -55,8 +55,8 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
|
|||
VariantList items;
|
||||
|
||||
// Set real dimensions
|
||||
_w = std::min(57 * fontWidth + HBORDER * 2, max_w);
|
||||
_h = std::min((16-2) * (lineHeight + VGAP) + 14 + _th, max_h);
|
||||
_w = std::min(55 * fontWidth + HBORDER * 2 + 8, max_w);
|
||||
_h = std::min(14 * (lineHeight + VGAP) + 14 + _th, max_h);
|
||||
|
||||
// The tab widget
|
||||
xpos = 2; ypos = 4;
|
||||
|
@ -94,6 +94,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
|
|||
SliderWidget* s = new SliderWidget(myTab, font, xpos, ypos - 1, swidth, lineHeight,
|
||||
"TIA zoom", lwidth, 0, fontWidth * 4, "%");
|
||||
s->setMinValue(200); s->setMaxValue(500);
|
||||
s->setTickmarkInterval(3); // just for testing now; TODO: remove or redefine
|
||||
wid.push_back(s);
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
|
@ -141,7 +142,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
|
|||
"(*) Requires application restart");
|
||||
|
||||
// Move over to the next column
|
||||
xpos += myFrameRate->getWidth() + 28;
|
||||
xpos += myFrameRate->getWidth() + 16;
|
||||
ypos = VBORDER;
|
||||
|
||||
// Fullscreen
|
||||
|
@ -236,7 +237,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
|
|||
CREATE_CUSTOM_SLIDERS(Fringe, "Fringing ");
|
||||
CREATE_CUSTOM_SLIDERS(Bleed, "Bleeding ");
|
||||
|
||||
xpos += myTVContrast->getWidth() + 40;
|
||||
xpos += myTVContrast->getWidth() + 30;
|
||||
ypos = VBORDER;
|
||||
|
||||
lwidth = font.getStringWidth("Intensity ");
|
||||
|
@ -389,7 +390,6 @@ void VideoDialog::saveConfig()
|
|||
// TIA Filter
|
||||
instance().settings().setValue("tia.zoom",
|
||||
myTIAZoom->getSelectedTag().toString());
|
||||
instance().frameBuffer().setZoomMode(instance().settings().getInt("tia.zoom"));
|
||||
|
||||
// TIA Palette
|
||||
instance().settings().setValue("palette",
|
||||
|
|
|
@ -638,7 +638,8 @@ SliderWidget::SliderWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_valueLabelGap(valueLabelGap),
|
||||
_valueLabelWidth(valueLabelWidth),
|
||||
_valueLabel(""),
|
||||
_valueUnit(valueUnit)
|
||||
_valueUnit(valueUnit),
|
||||
_numIntervals(0)
|
||||
{
|
||||
_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE;
|
||||
_bgcolor = kDlgColor;
|
||||
|
@ -721,6 +722,13 @@ void SliderWidget::setValueUnit(const string& valueUnit)
|
|||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SliderWidget::setTickmarkInterval(int numIntervals)
|
||||
{
|
||||
_numIntervals = numIntervals;
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SliderWidget::handleMouseMoved(int x, int y)
|
||||
{
|
||||
|
@ -816,6 +824,30 @@ void SliderWidget::drawWidget(bool hilite)
|
|||
// Draw the 'bar'
|
||||
s.fillRect(x, y, p, h,
|
||||
!isEnabled() ? kColor : hilite ? kSliderColorHi : kSliderColor);
|
||||
|
||||
// Draw the 'tickmarks'
|
||||
for(int i = 1; i < _numIntervals; ++i)
|
||||
{
|
||||
int xt = x + (_w - _labelWidth - _valueLabelGap - _valueLabelWidth) * i / _numIntervals - 1;
|
||||
uInt32 color;
|
||||
|
||||
if(isEnabled())
|
||||
{
|
||||
if(xt > x + p)
|
||||
color = hilite ? kSliderColorHi : kSliderColor;
|
||||
else
|
||||
color = hilite ? kSliderBGColorHi : kSliderBGColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(xt > x + p)
|
||||
color = kColor;
|
||||
else
|
||||
color = kSliderBGColorLo;
|
||||
}
|
||||
s.vLine(xt, y + h / 2, y + h - 1, color);
|
||||
}
|
||||
|
||||
// Draw the 'handle'
|
||||
s.fillRect(x + p, y - 2, 2, h + 4,
|
||||
!isEnabled() ? kColor : hilite ? kSliderColorHi : kSliderColor);
|
||||
|
|
|
@ -328,6 +328,8 @@ class SliderWidget : public ButtonWidget
|
|||
const string& getValueLabel() const { return _valueLabel; }
|
||||
void setValueUnit(const string& valueUnit);
|
||||
|
||||
void setTickmarkInterval(int numIntervals);
|
||||
|
||||
protected:
|
||||
void handleMouseMoved(int x, int y) override;
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
|
@ -349,6 +351,7 @@ class SliderWidget : public ButtonWidget
|
|||
string _valueUnit;
|
||||
int _valueLabelWidth;
|
||||
int _valueLabelGap;
|
||||
int _numIntervals;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* Localized versions of Info.plist keys */
|
||||
|
||||
CFBundleName = "Stella";
|
||||
CFBundleShortVersionString = "Stella version 5.0.2";
|
||||
CFBundleGetInfoString = "Stella version 5.0.2";
|
||||
CFBundleShortVersionString = "Stella version 5.1";
|
||||
CFBundleGetInfoString = "Stella version 5.1";
|
||||
NSHumanReadableCopyright = "Stella MacOS X version by Stephen Anthony and Mark Grebe.";
|
||||
|
||||
"Atari 2600 Cartridge File" = "Atari 2600 Cartridge File";
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<key>CFBundleSignature</key>
|
||||
<string>StLa</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>5.0.2</string>
|
||||
<string>5.1</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSMinimumSystemVersionByArchitecture</key>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%define name stella
|
||||
%define version 5.0.2
|
||||
%define version 5.1
|
||||
%define rel 1
|
||||
|
||||
%define enable_sound 1
|
||||
|
@ -101,6 +101,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version}
|
|||
%_datadir/icons/large/%{name}.png
|
||||
|
||||
%changelog
|
||||
* Sun Feb 04 2018 Stephen Anthony <stephena@users.sf.net> 5.1-1
|
||||
- Version 5.1 release
|
||||
|
||||
* Sun Aug 20 2017 Stephen Anthony <stephena@users.sf.net> 5.0.2-1
|
||||
- Version 5.0.2 release
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ IDI_ICON ICON "stella.ico"
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 5,0,2,0
|
||||
PRODUCTVERSION 5,0,2,0
|
||||
FILEVERSION 5,1,0,0
|
||||
PRODUCTVERSION 5,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -55,12 +55,12 @@ BEGIN
|
|||
VALUE "Comments", "The multi-platform Atari 2600 emulator. Stella is released under the GPLv2."
|
||||
VALUE "CompanyName", "The Stella Team (https://stella-emu.github.io)"
|
||||
VALUE "FileDescription", "Stella"
|
||||
VALUE "FileVersion", "5.0.2"
|
||||
VALUE "FileVersion", "5.1"
|
||||
VALUE "InternalName", "Stella"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1995-2018 The Stella Team"
|
||||
VALUE "OriginalFilename", "Stella.exe"
|
||||
VALUE "ProductName", "Stella"
|
||||
VALUE "ProductVersion", "5.0.2"
|
||||
VALUE "ProductVersion", "5.1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Loading…
Reference in New Issue