mirror of https://github.com/stella-emu/stella.git
Merge branch 'release/5.1'
This commit is contained in:
commit
f7c445fb7c
22
Announce.txt
22
Announce.txt
|
@ -9,7 +9,7 @@
|
||||||
SSSS ttt eeeee llll llll aaaaa
|
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
|
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
|
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 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:
|
distributions currently available are:
|
||||||
|
|
||||||
* Binaries for Windows XP_SP3(*)/Vista/7/8/10 :
|
* Binaries for Windows XP_SP3(*)/Vista/7/8/10 :
|
||||||
Stella-5.0.2-win32.exe (32-bit EXE installer)
|
Stella-5.1-win32.exe (32-bit EXE installer)
|
||||||
Stella-5.0.2-x64.exe (64-bit EXE installer)
|
Stella-5.1-x64.exe (64-bit EXE installer)
|
||||||
Stella-5.0.2-windows.zip (32/64 bit versions)
|
Stella-5.1-windows.zip (32/64 bit versions)
|
||||||
|
|
||||||
(*) Note: Support for Windows XP is problematic on some systems,
|
(*) Note: Support for Windows XP is problematic on some systems,
|
||||||
and will probably be discontinued in a future release.
|
and will probably be discontinued in a future release.
|
||||||
|
|
||||||
* Binary distribution for MacOS X 10.7 and above :
|
* 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 :
|
* Binary distribution in 32-bit & 64-bit Ubuntu DEB format :
|
||||||
stella_5.0.2-1_i386.deb
|
stella_5.1-1_i386.deb
|
||||||
stella_5.0.2-1_amd64.deb
|
stella_5.1-1_amd64.deb
|
||||||
|
|
||||||
* Binary distribution in 32-bit & 64-bit RPM format :
|
* Binary distribution in 32-bit & 64-bit RPM format :
|
||||||
stella-5.0.2-2.i386.rpm
|
stella-5.1-2.i386.rpm
|
||||||
stella-5.0.2-2.x86_64.rpm
|
stella-5.1-2.x86_64.rpm
|
||||||
|
|
||||||
* Source code distribution for all platforms :
|
* Source code distribution for all platforms :
|
||||||
stella-5.0.2-src.tar.xz
|
stella-5.1-src.tar.xz
|
||||||
|
|
||||||
|
|
||||||
Distribution Site
|
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.
|
* Added "Time Machine" mode, which automatically creates save states
|
||||||
|
in user-defined intervals. The user can navigate back and forth within
|
||||||
* Don't trap write accesses to the datastream pointers in CDF and BUS.
|
these states inside the emulator and the debugger.
|
||||||
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++.
|
|
||||||
|
|
||||||
* Huge improvements to the disassembly view in the debugger and
|
* Huge improvements to the disassembly view in the debugger and
|
||||||
disassembly files created:
|
disassembly files created:
|
||||||
|
@ -23,9 +13,30 @@
|
||||||
- improved cycle count (page penalties, sums created in disassembly)
|
- improved cycle count (page penalties, sums created in disassembly)
|
||||||
- improved handling of instruction masking opcodes (e.g. BIT)
|
- improved handling of instruction masking opcodes (e.g. BIT)
|
||||||
|
|
||||||
* Added "Time Machine" mode, which automatically creates save states
|
* Fixed change tracking bug during rewind; changes were accumulated
|
||||||
in user-defined intervals. The user can navigate back and forth within
|
instead of being displayed only for the last rewind step.
|
||||||
these states inside the emulator and the 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.
|
||||||
|
|
||||||
|
* 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).
|
* Fixed Genesis controller autodetect (Stay Frosty 2, Scramble, etc).
|
||||||
|
|
||||||
|
@ -48,9 +59,6 @@
|
||||||
information). In the case of 'saveses', the filename is now named
|
information). In the case of 'saveses', the filename is now named
|
||||||
based on the date and time of when the command was entered.
|
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
|
* Fixed bug with saving snapshots in 1x mode; there was graphical
|
||||||
corruption in some cases. Such snapshots also now include any TV
|
corruption in some cases. Such snapshots also now include any TV
|
||||||
effects / phosphor blending currently in use.
|
effects / phosphor blending currently in use.
|
||||||
|
@ -72,22 +80,16 @@
|
||||||
all ROMs or only the current one. Also added a message (configurable)
|
all ROMs or only the current one. Also added a message (configurable)
|
||||||
when the flash memory is accessed.
|
when the flash memory is accessed.
|
||||||
|
|
||||||
* Moved various developer related settings in new Developer Settings
|
* Access to the AtariVox/SaveKey can be signaled with a message.
|
||||||
dialog. These settings now come in two groups (player/developer) and
|
|
||||||
allow switching all settings at once.
|
|
||||||
|
|
||||||
* 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
|
* Added conditional traps and savestate creation to debugger.
|
||||||
multiple states.
|
|
||||||
|
|
||||||
* Added 'unwind' command, which undoes the latest rewind(s)
|
|
||||||
|
|
||||||
* Added '<' (unwind) button to debugger.
|
|
||||||
|
|
||||||
* Added 'Options...' button to debugger which gives access to the options
|
* Added 'Options...' button to debugger which gives access to the options
|
||||||
menu during debugging.
|
menu during debugging.
|
||||||
|
@ -107,7 +109,7 @@
|
||||||
* Improved change tracking; more values are tracked and change tracking
|
* Improved change tracking; more values are tracked and change tracking
|
||||||
now works in case of a break too.
|
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,
|
* Improved emulation of 'FE' bankswitch scheme (no user-visible changes,
|
||||||
but internally the emulation is much more accurate compared to the
|
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
|
* Added ROM properties for 'Zippy the Porcupine' ROMs, and updated
|
||||||
info for all "Chris Spry (Sprybug)" ROMs.
|
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
|
* Fixed error when building with uClibc-ng for ARM (thanks to Sergio
|
||||||
Prado).
|
Prado).
|
||||||
|
|
||||||
|
|
|
@ -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
|
stella (5.0.2-1) stable; urgency=high
|
||||||
|
|
||||||
* Version 5.0.2 release
|
* Version 5.0.2 release
|
||||||
|
|
|
@ -348,27 +348,27 @@ size can be configured e.g. in the
|
||||||
<td>Frame+1</td>
|
<td>Frame+1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Control-r</td>
|
<td>Alt-Left arrow</td>
|
||||||
<td>Rewind 1</td>
|
<td>Rewind 1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Control-Shift-r</td>
|
<td>Shift-Alt-Left arrow</td>
|
||||||
<td>Rewind 10</td>
|
<td>Rewind 10</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Control-Alt-r</td>
|
<td>Alt-Down arrow</td>
|
||||||
<td>Rewind all</td>
|
<td>Rewind all</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Control-y</td>
|
<td>Alt-Right arrow</td>
|
||||||
<td>Unwind 1</td>
|
<td>Unwind 1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Control-Shift-y</td>
|
<td>Shift-Alt-Right arrow</td>
|
||||||
<td>Unwind 10</td>
|
<td>Unwind 10</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Control-Alt-y</td>
|
<td>Alt-Up arrow</td>
|
||||||
<td>Unwind all</td>
|
<td>Unwind all</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -377,6 +377,7 @@ size can be configured e.g. in the
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
|
For MacOS use 'Cmd' instead of 'Alt' key.
|
||||||
<p>To the left of the global buttons, you find the "Options..." button.</p>
|
<p>To the left of the global buttons, you find the "Options..." button.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<p><img src="graphics/debugger_options.png"></p>
|
<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 |
101
docs/index.html
101
docs/index.html
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
<br><br><br>
|
<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>The Stella Team</b></center>
|
||||||
<center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center>
|
<center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center>
|
||||||
|
|
||||||
|
@ -1622,32 +1622,38 @@
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<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>Alt + Left arrow</td>
|
||||||
<td>Cmd + Left arrow</td>
|
<td>Cmd + Left arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
<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-Alt + Left arrow</td>
|
||||||
<td>Shift-Cmd + Left arrow</td>
|
<td>Shift-Cmd + Left arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
<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>Alt + Down arrow</td>
|
||||||
<td>Cmd + Down arrow</td>
|
<td>Cmd + Down arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
<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>Alt + Right arrow</td>
|
||||||
<td>Cmd + Right arrow</td>
|
<td>Cmd + Right arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
<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-Alt + Right arrow</td>
|
||||||
<td>Shift-Cmd + Right arrow</td>
|
<td>Shift-Cmd + Right arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
<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>Alt + Up arrow</td>
|
||||||
<td>Cmd + Up arrow</td>
|
<td>Cmd + Up arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -1794,36 +1800,49 @@
|
||||||
<a name="TimeMachine">Stella's 'Time Machine'</a></h2>
|
<a name="TimeMachine">Stella's 'Time Machine'</a></h2>
|
||||||
|
|
||||||
<p>A special feature of Stella is the 'Time Machine' mode. In this mode, Stella
|
<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
|
automatically creates savestates in regular, user-defined intervals. At any time,
|
||||||
interrupt the current emulation and navigate back and forth within the timeline.
|
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
|
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
|
<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>
|
<p><b>Time Machine</b> dialog:</p>
|
||||||
<table border="5" cellpadding="2" frame="box" rules="none">
|
<td><img src="graphics/timemachine.png"></td>
|
||||||
<tr>
|
|
||||||
<td>TODO: Screenshot</td>
|
<p>The dialog items are explained in the following two tables.</p>
|
||||||
<td> </td>
|
|
||||||
<td valign="top">
|
<p><b>Top row (left to right)</b></p>
|
||||||
<table border="1" cellpadding="4">
|
<table border="1" cellpadding="4">
|
||||||
<tr><th>Item</th><th>Description</th></tr>
|
<tr><th>Item</th><th>Description</th></tr>
|
||||||
<tr><td>Button</td><td>TODO</td></tr>
|
<tr><td>Current state</td><td>Shows the currently loaded state's number</td></tr>
|
||||||
<tr><td>Button</td><td></td></tr>
|
<tr><td>'Timeline' slider</td><td>Shows the position of the current state in the
|
||||||
<tr><td>Button</td><td></td></tr>
|
recorded timeline. A state can be selected by dragging the slider with the mouse.
|
||||||
<tr><td>Button</td><td></td></tr>
|
To visualize state compression, small marks split the timeline into five, equally
|
||||||
<tr><td>Button</td><td></td></tr>
|
sized state number intervals.</td></tr>
|
||||||
<tr><td>Button</td><td></td></tr>
|
<tr><td>Total states</td><td>Shows the total number of save states in the
|
||||||
<tr><td>Button</td><td></td></tr>
|
Time Machine</td></tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
<p><b>Bottom row (left to right)</b></p>
|
||||||
</tr>
|
<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>
|
</table>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
<p>The 'Time Machine' mode can be configured by the user. For details see
|
<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>
|
<br><br>
|
||||||
|
@ -2540,8 +2559,12 @@
|
||||||
<td>The default of true allows the Thumb ARM emulation to
|
<td>The default of true allows the Thumb ARM emulation to
|
||||||
throw an exception and enter the debugger on fatal errors. When disabled, such
|
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
|
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
|
unless you know exactly what you're doing, as it changes the behaviour as
|
||||||
to real hardware.</td>
|
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>
|
</tr><tr>
|
||||||
<td><pre>-<plr.|dev.>tv.jitter <1|0></pre></td>
|
<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
|
<td>Enable TV jitter/roll effect, when there are too many or too few scanlines
|
||||||
|
@ -2740,13 +2763,15 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</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">
|
<table border="5" cellpadding="2" frame="box" rules="none">
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="graphics/romaudit.png"></td>
|
<td><img src="graphics/options_developer.png"></td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td valign="top"><br>This dialog is described in further detail in
|
<td valign="top"><br>This tab is described in further detail in
|
||||||
<b>Advanced Configuration - <a href="#ROMAudit">ROM Audit Mode</a></b>.</td>
|
<b>Advanced Configuration - <a href="#Debugger">Developer Options/Integrated Debugger</a></b>.</td>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<br>
|
<br>
|
||||||
|
@ -2760,18 +2785,17 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<p><b>Developer Settings</b> dialog:</p>
|
<p><b>Audit ROMs</b> dialog:</p>
|
||||||
<table border="5" cellpadding="2" frame="box" rules="none">
|
<table border="5" cellpadding="2" frame="box" rules="none">
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="graphics/options_developer.png"></td>
|
<td><img src="graphics/romaudit.png"></td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td valign="top"><br>This tab is described in further detail in
|
<td valign="top"><br>This dialog is described in further detail in
|
||||||
<b>Advanced Configuration - <a href="#Debugger">Developer Options/Integrated Debugger</a></b>.</td>
|
<b>Advanced Configuration - <a href="#ROMAudit">ROM Audit Mode</a></b>.</td>
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<br>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<h2><b><a name="Remapping">Event Remapping/Input Devices</a></b></h2>
|
<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>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>
|
<td><span style="white-space:nowrap">-plr.thumb.trapfatal<br/>-dev.thumb.trapfatal</span></td>
|
||||||
</tr>
|
</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>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -78,6 +78,9 @@ class LinkedObjectPool
|
||||||
SLOW, but only required for messages
|
SLOW, but only required for messages
|
||||||
*/
|
*/
|
||||||
uInt32 currentIdx() const {
|
uInt32 currentIdx() const {
|
||||||
|
if(empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
iter it = myCurrent;
|
iter it = myCurrent;
|
||||||
uInt32 idx = 1;
|
uInt32 idx = 1;
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,6 @@ string RewindManager::getUnitString(Int64 cycles)
|
||||||
const Int32 PAL_FREQ = 1182298; // ~76*312*50
|
const Int32 PAL_FREQ = 1182298; // ~76*312*50
|
||||||
const Int32 freq = isNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second
|
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 Int32 NUM_UNITS = 5;
|
||||||
const string UNIT_NAMES[NUM_UNITS] = { "cycle", "scanline", "frame", "second", "minute" };
|
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 };
|
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
|
// 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?
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
result << cycles / UNIT_CYCLES[i] << " " << UNIT_NAMES[i];
|
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 !myStateList.empty() ? myStateList.first()->cycles : 0;
|
||||||
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.first())->cycles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 RewindManager::getCurrentCycles() const
|
uInt64 RewindManager::getCurrentCycles() const
|
||||||
{
|
{
|
||||||
if(myStateList.currentIsValid())
|
if(myStateList.currentIsValid())
|
||||||
return myStateList.current().cycles;
|
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 !myStateList.empty() ? myStateList.last()->cycles : 0;
|
||||||
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.last())->cycles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -149,9 +149,9 @@ class RewindManager
|
||||||
uInt32 getCurrentIdx() { return myStateList.currentIdx(); }
|
uInt32 getCurrentIdx() { return myStateList.currentIdx(); }
|
||||||
uInt32 getLastIdx() { return myStateList.size(); }
|
uInt32 getLastIdx() { return myStateList.size(); }
|
||||||
|
|
||||||
uInt32 getFirstCycles() const;
|
uInt64 getFirstCycles() const;
|
||||||
uInt32 getCurrentCycles() const;
|
uInt64 getCurrentCycles() const;
|
||||||
uInt32 getLastCycles() const;
|
uInt64 getLastCycles() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a collection of cycle timestamps, offset from the first one in
|
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]); }
|
T pop() { return std::move(_stack[--_size]); }
|
||||||
uInt32 size() const { return _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
|
// Apply the given function to every item in the stack
|
||||||
// We do it this way so the stack API can be preserved,
|
// We do it this way so the stack API can be preserved,
|
||||||
// and no access to individual elements is allowed outside
|
// and no access to individual elements is allowed outside
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "StateManager.hxx"
|
#include "StateManager.hxx"
|
||||||
|
|
||||||
#define STATE_HEADER "05009901state"
|
#define STATE_HEADER "05010000state"
|
||||||
// #define MOVIE_HEADER "03030000movie"
|
// #define MOVIE_HEADER "03030000movie"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#ifndef VERSION_HXX
|
#ifndef VERSION_HXX
|
||||||
#define VERSION_HXX
|
#define VERSION_HXX
|
||||||
|
|
||||||
#define STELLA_VERSION "5.1_b1"
|
#define STELLA_VERSION "5.1"
|
||||||
#define STELLA_BUILD "3826"
|
#define STELLA_BUILD "4138"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,6 +76,7 @@ using std::memcpy;
|
||||||
|
|
||||||
// Common array types
|
// Common array types
|
||||||
using IntArray = std::vector<Int32>;
|
using IntArray = std::vector<Int32>;
|
||||||
|
using uIntArray = std::vector<uInt32>;
|
||||||
using BoolArray = std::vector<bool>;
|
using BoolArray = std::vector<bool>;
|
||||||
using ByteArray = std::vector<uInt8>;
|
using ByteArray = std::vector<uInt8>;
|
||||||
using ShortArray = std::vector<uInt16>;
|
using ShortArray = std::vector<uInt16>;
|
||||||
|
|
|
@ -301,19 +301,19 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
||||||
{
|
{
|
||||||
case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states
|
case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states
|
||||||
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, false);
|
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, false);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states
|
case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states
|
||||||
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, true);
|
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, true);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
case KBDK_DOWN: // Alt-down rewinds to start of list
|
case KBDK_DOWN: // Alt-down rewinds to start of list
|
||||||
enterTimeMachineMenuMode(1000, false);
|
enterTimeMachineMenuMode(1000, false);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
case KBDK_UP: // Alt-up rewinds to end of list
|
case KBDK_UP: // Alt-up rewinds to end of list
|
||||||
enterTimeMachineMenuMode(1000, true);
|
enterTimeMachineMenuMode(1000, true);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
// These can work in pause mode too
|
// These can work in pause mode too
|
||||||
case KBDK_EQUALS:
|
case KBDK_EQUALS:
|
||||||
|
@ -2151,6 +2151,8 @@ void EventHandler::enterTimeMachineMenuMode(uInt32 numWinds, bool unwind)
|
||||||
// add one extra state if we are in Time Machine mode
|
// 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
|
// TODO: maybe remove this state if we leave the menu at this new state
|
||||||
myOSystem.state().addExtraState("enter Time Machine dialog"); // force new state
|
myOSystem.state().addExtraState("enter Time Machine dialog"); // force new state
|
||||||
|
if(numWinds)
|
||||||
|
myOSystem.state().windStates(numWinds, unwind);
|
||||||
|
|
||||||
if(numWinds)
|
if(numWinds)
|
||||||
myOSystem.state().windStates(numWinds, unwind);
|
myOSystem.state().windStates(numWinds, unwind);
|
||||||
|
@ -2197,6 +2199,7 @@ void EventHandler::setEventState(EventHandlerState state)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EventHandlerState::TIMEMACHINE:
|
case EventHandlerState::TIMEMACHINE:
|
||||||
|
myOSystem.timeMachine().requestResize();
|
||||||
myOverlay = &myOSystem.timeMachine();
|
myOverlay = &myOSystem.timeMachine();
|
||||||
enableTextEvents(true);
|
enableTextEvents(true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -150,7 +150,6 @@ bool FrameBuffer::initialize()
|
||||||
FBSurface::setPalette(myPalette);
|
FBSurface::setPalette(myPalette);
|
||||||
|
|
||||||
myGrabMouse = myOSystem.settings().getBool("grabmouse");
|
myGrabMouse = myOSystem.settings().getBool("grabmouse");
|
||||||
myZoomMode = myOSystem.settings().getInt("tia.zoom");
|
|
||||||
|
|
||||||
// Create a TIA surface; we need it for rendering TIA images
|
// Create a TIA surface; we need it for rendering TIA images
|
||||||
myTIASurface = make_unique<TIASurface>(myOSystem);
|
myTIASurface = make_unique<TIASurface>(myOSystem);
|
||||||
|
@ -238,7 +237,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
|
||||||
{
|
{
|
||||||
myStatsMsg.surface = allocateSurface(myStatsMsg.w, myStatsMsg.h);
|
myStatsMsg.surface = allocateSurface(myStatsMsg.w, myStatsMsg.h);
|
||||||
myStatsMsg.surface->attributes().blending = true;
|
myStatsMsg.surface->attributes().blending = true;
|
||||||
//myStatsMsg.surface->attributes().blendalpha = 80;
|
myStatsMsg.surface->attributes().blendalpha = 92; //aligned with TimeMachineDialog
|
||||||
myStatsMsg.surface->applyAttributes();
|
myStatsMsg.surface->applyAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,9 +386,10 @@ void FrameBuffer::drawFrameStats()
|
||||||
|
|
||||||
myStatsMsg.surface->invalidate();
|
myStatsMsg.surface->invalidate();
|
||||||
string bsinfo = info.BankSwitch +
|
string bsinfo = info.BankSwitch +
|
||||||
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player");
|
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "");
|
||||||
// draw shadowed text
|
// 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());
|
std::snprintf(msg, 30, "%3u", myOSystem.console().tia().scanlinesLastFrame());
|
||||||
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
||||||
myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor);
|
myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor);
|
||||||
|
@ -404,8 +404,11 @@ void FrameBuffer::drawFrameStats()
|
||||||
float frameRate;
|
float frameRate;
|
||||||
/*if(myOSystem.settings().getInt("framerate") == 0)
|
/*if(myOSystem.settings().getInt("framerate") == 0)
|
||||||
{
|
{
|
||||||
// if 'Auto' is selected, draw the calculated framerate
|
frameRate = 1000000.0 * (ti.totalFrames - myTotalFrames) / (ti.totalTime - myTotalTime);
|
||||||
frameRate = myOSystem.console().getFramerate();
|
if(frameRate > myOSystem.console().getFramerate() + 1)
|
||||||
|
frameRate = 1; // check soon again
|
||||||
|
myTotalFrames = ti.totalFrames;
|
||||||
|
myTotalTime = ti.totalTime;
|
||||||
}
|
}
|
||||||
else*/
|
else*/
|
||||||
{
|
{
|
||||||
|
@ -427,13 +430,13 @@ void FrameBuffer::drawFrameStats()
|
||||||
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
||||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||||
|
|
||||||
|
// draw bankswitching type
|
||||||
myStatsMsg.surface->drawString(font(), bsinfo, XPOS, YPOS + font().getFontHeight(),
|
myStatsMsg.surface->drawString(font(), bsinfo, XPOS, YPOS + font().getFontHeight(),
|
||||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||||
|
|
||||||
myStatsMsg.surface->setDirty();
|
myStatsMsg.surface->setDirty();
|
||||||
myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1);
|
myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8);
|
||||||
myStatsMsg.surface->render();
|
myStatsMsg.surface->render();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -654,7 +657,7 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
|
||||||
|
|
||||||
resetSurfaces();
|
resetSurfaces();
|
||||||
showMessage(mode.description);
|
showMessage(mode.description);
|
||||||
myZoomMode = mode.zoom;
|
myOSystem.settings().setValue("tia.zoom", mode.zoom);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -813,17 +816,11 @@ const VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
|
||||||
if(state == EventHandlerState::DEBUGGER || state == EventHandlerState::LAUNCHER)
|
if(state == EventHandlerState::DEBUGGER || state == EventHandlerState::LAUNCHER)
|
||||||
myCurrentModeList->setZoom(1);
|
myCurrentModeList->setZoom(1);
|
||||||
else
|
else
|
||||||
myCurrentModeList->setZoom(myZoomMode);
|
myCurrentModeList->setZoom(myOSystem.settings().getInt("tia.zoom"));
|
||||||
|
|
||||||
return myCurrentModeList->current();
|
return myCurrentModeList->current();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void FrameBuffer::setZoomMode(uInt32 mode)
|
|
||||||
{
|
|
||||||
myZoomMode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
//
|
//
|
||||||
// VideoMode implementation
|
// VideoMode implementation
|
||||||
|
|
|
@ -192,11 +192,6 @@ class FrameBuffer
|
||||||
*/
|
*/
|
||||||
const VariantList& supportedTIAZoomLevels() const { return myTIAZoomLevels; }
|
const VariantList& supportedTIAZoomLevels() const { return myTIAZoomLevels; }
|
||||||
|
|
||||||
/*
|
|
||||||
Set the current zoom mode.
|
|
||||||
*/
|
|
||||||
void setZoomMode(uInt32 mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the font object(s) of the framebuffer
|
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
|
// Names of the TIA zoom levels that can be used for this framebuffer
|
||||||
VariantList myTIAZoomLevels;
|
VariantList myTIAZoomLevels;
|
||||||
|
|
||||||
// curently selected zoom mode
|
|
||||||
uInt32 myZoomMode;
|
|
||||||
|
|
||||||
// Holds a reference to all the surfaces that have been created
|
// Holds a reference to all the surfaces that have been created
|
||||||
vector<shared_ptr<FBSurface>> mySurfaceList;
|
vector<shared_ptr<FBSurface>> mySurfaceList;
|
||||||
|
|
||||||
|
|
|
@ -1229,6 +1229,8 @@ void TIA::tickHblank()
|
||||||
if (myExtendedHblank) myHstate = HState::frame;
|
if (myExtendedHblank) myHstate = HState::frame;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (myExtendedHblank && myHctr > 67) myPlayfield.tick(myHctr - 68 - myHctrDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1269,6 +1271,7 @@ void TIA::nextLine()
|
||||||
cloneLastLine();
|
cloneLastLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myPlayfield.tick(0);
|
||||||
myHctr = 0;
|
myHctr = 0;
|
||||||
|
|
||||||
if (!myMovementInProgress && myLinesSinceChange < 2) myLinesSinceChange++;
|
if (!myMovementInProgress && myLinesSinceChange < 2) myLinesSinceChange++;
|
||||||
|
|
|
@ -75,7 +75,8 @@ class Dialog : public GuiObject
|
||||||
/** Returns the base surface associated with this dialog. */
|
/** Returns the base surface associated with this dialog. */
|
||||||
FBSurface& surface() const { return *_surface; }
|
FBSurface& surface() const { return *_surface; }
|
||||||
|
|
||||||
/** Adds a surface to this dialog, which is rendered on top of the
|
/**
|
||||||
|
Adds a surface to this dialog, which is rendered on top of the
|
||||||
base surface whenever the base surface is re-rendered. Since
|
base surface whenever the base surface is re-rendered. Since
|
||||||
the surface render() call will always occur in such a case, the
|
the surface render() call will always occur in such a case, the
|
||||||
surface should call setVisible() to enable/disable its output.
|
surface should call setVisible() to enable/disable its output.
|
||||||
|
@ -89,6 +90,11 @@ class Dialog : public GuiObject
|
||||||
void setTitle(const string& title);
|
void setTitle(const string& title);
|
||||||
bool hasTitle() { return !_title.empty(); }
|
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:
|
protected:
|
||||||
virtual void draw() override { }
|
virtual void draw() override { }
|
||||||
void releaseFocus() override;
|
void releaseFocus() override;
|
||||||
|
@ -123,11 +129,6 @@ class Dialog : public GuiObject
|
||||||
|
|
||||||
void processCancelWithoutWidget(bool state) { _processCancel = state; }
|
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);
|
void initTitle(const GUI::Font& font, const string& title);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -119,7 +119,7 @@ void DialogContainer::addDialog(Dialog* d)
|
||||||
const GUI::Rect& r = myOSystem.frameBuffer().imageRect();
|
const GUI::Rect& r = myOSystem.frameBuffer().imageRect();
|
||||||
if(uInt32(d->getWidth()) > r.width() || uInt32(d->getHeight()) > r.height())
|
if(uInt32(d->getWidth()) > r.width() || uInt32(d->getHeight()) > r.height())
|
||||||
myOSystem.frameBuffer().showMessage(
|
myOSystem.frameBuffer().showMessage(
|
||||||
"Unable to show dialog box; resize current window");
|
"Unable to show dialog box; FIX THE CODE");
|
||||||
else
|
else
|
||||||
myDialogStack.push(d);
|
myDialogStack.push(d);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,14 @@ class DialogContainer
|
||||||
*/
|
*/
|
||||||
const Dialog* baseDialog() const { return myBaseDialog; }
|
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:
|
private:
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
b = ADD_OD_BUTTON("Developer" + ELLIPSIS, kDevelopCmd);
|
b = ADD_OD_BUTTON("Developer" + ELLIPSIS, kDevelopCmd);
|
||||||
wid.push_back(b);
|
wid.push_back(b);
|
||||||
|
|
||||||
|
|
||||||
// Move to second column
|
// Move to second column
|
||||||
xoffset += buttonWidth + 10; yoffset = VBORDER;
|
xoffset += buttonWidth + 10; yoffset = VBORDER;
|
||||||
|
|
||||||
|
|
|
@ -25,18 +25,14 @@
|
||||||
|
|
||||||
#include "TimeLineWidget.hxx"
|
#include "TimeLineWidget.hxx"
|
||||||
|
|
||||||
// TODO - remove all references to _stepValue__
|
|
||||||
// - fix posToValue to use _stepValue
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
int x, int y, int w, int h,
|
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),
|
: ButtonWidget(boss, font, x, y, w, h, label, cmd),
|
||||||
_value(0),
|
_value(0),
|
||||||
_stepValue__(1),
|
|
||||||
_valueMin(0),
|
_valueMin(0),
|
||||||
_valueMax(100),
|
_valueMax(0),
|
||||||
_isDragging(false),
|
_isDragging(false),
|
||||||
_labelWidth(labelWidth)
|
_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;
|
value = BSPF::clamp(value, _valueMin, _valueMax);
|
||||||
else if(value > _valueMax) value = _valueMax;
|
|
||||||
|
|
||||||
if(value != _value)
|
if(value != _value)
|
||||||
{
|
{
|
||||||
|
@ -67,13 +62,13 @@ void TimeLineWidget::setValue(int value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TimeLineWidget::setMinValue(int value)
|
void TimeLineWidget::setMinValue(uInt32 value)
|
||||||
{
|
{
|
||||||
_valueMin = value;
|
_valueMin = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TimeLineWidget::setMaxValue(int value)
|
void TimeLineWidget::setMaxValue(uInt32 value)
|
||||||
{
|
{
|
||||||
_valueMax = value;
|
_valueMax = value;
|
||||||
}
|
}
|
||||||
|
@ -81,12 +76,16 @@ void TimeLineWidget::setMaxValue(int value)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TimeLineWidget::setStepValues(const IntArray& steps)
|
void TimeLineWidget::setStepValues(const IntArray& steps)
|
||||||
{
|
{
|
||||||
|
_stepValue.clear();
|
||||||
|
|
||||||
|
// If no steps are defined, just use the maximum value
|
||||||
|
if(steps.size() > 0)
|
||||||
|
{
|
||||||
// Try to allocate as infrequently as possible
|
// Try to allocate as infrequently as possible
|
||||||
if(steps.size() > _stepValue.capacity())
|
if(steps.size() > _stepValue.capacity())
|
||||||
_stepValue.reserve(2 * steps.size());
|
_stepValue.reserve(2 * steps.size());
|
||||||
_stepValue.clear();
|
|
||||||
|
|
||||||
double scale = (_w - _labelWidth - 4) / double(steps.back());
|
double scale = (_w - _labelWidth - 2) / double(steps.back());
|
||||||
|
|
||||||
// Skip the very last value; we take care of it outside the end of the loop
|
// 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)
|
for(uInt32 i = 0; i < steps.size() - 1; ++i)
|
||||||
|
@ -94,14 +93,15 @@ void TimeLineWidget::setStepValues(const IntArray& steps)
|
||||||
|
|
||||||
// Due to integer <-> double conversion, the last value is sometimes
|
// Due to integer <-> double conversion, the last value is sometimes
|
||||||
// slightly less than the maximum value; we assign it manually to fix this
|
// slightly less than the maximum value; we assign it manually to fix this
|
||||||
_stepValue.push_back(_w - _labelWidth - 4);
|
_stepValue.push_back(_w - _labelWidth - 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_stepValue.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TimeLineWidget::handleMouseMoved(int x, int y)
|
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))
|
if(isEnabled() && _isDragging && x >= int(_labelWidth))
|
||||||
setValue(posToValue(x - _labelWidth));
|
setValue(posToValue(x - _labelWidth));
|
||||||
}
|
}
|
||||||
|
@ -130,47 +130,13 @@ void TimeLineWidget::handleMouseWheel(int x, int y, int direction)
|
||||||
{
|
{
|
||||||
if(isEnabled())
|
if(isEnabled())
|
||||||
{
|
{
|
||||||
if(direction < 0)
|
if(direction < 0 && _value < _valueMax)
|
||||||
handleEvent(Event::UIUp);
|
setValue(_value + 1);
|
||||||
else if(direction > 0)
|
else if(direction > 0 && _value > _valueMin)
|
||||||
handleEvent(Event::UIDown);
|
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)
|
void TimeLineWidget::drawWidget(bool hilite)
|
||||||
{
|
{
|
||||||
|
@ -183,13 +149,26 @@ void TimeLineWidget::drawWidget(bool hilite)
|
||||||
isEnabled() ? kTextColor : kColor, TextAlign::Right);
|
isEnabled() ? kTextColor : kColor, TextAlign::Right);
|
||||||
|
|
||||||
// Draw the box
|
// 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
|
// 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);
|
!isEnabled() ? kBGColorHi : kWidColor);
|
||||||
// Draw the 'bar'
|
// 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);
|
!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
|
#else
|
||||||
// Draw the label, if any
|
// Draw the label, if any
|
||||||
if(_labelWidth > 0)
|
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;
|
return _stepValue[BSPF::clamp(value, _valueMin, _valueMax)];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
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 _valueMax;
|
||||||
return value - (value % _stepValue__);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,15 +25,15 @@ class TimeLineWidget : public ButtonWidget
|
||||||
public:
|
public:
|
||||||
TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
int x, int y, int w, int h, const string& label = "",
|
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);
|
void setValue(uInt32 value);
|
||||||
int getValue() const { return _value; }
|
uInt32 getValue() const { return _value; }
|
||||||
|
|
||||||
void setMinValue(int value);
|
void setMinValue(uInt32 value);
|
||||||
int getMinValue() const { return _valueMin; }
|
void setMaxValue(uInt32 value);
|
||||||
void setMaxValue(int value);
|
uInt32 getMinValue() const { return _valueMin; }
|
||||||
int getMaxValue() const { return _valueMax; }
|
uInt32 getMaxValue() const { return _valueMax; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Steps are not necessarily linear in a timeline, so we need info
|
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 handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||||
void handleMouseUp(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;
|
void handleMouseWheel(int x, int y, int direction) override;
|
||||||
bool handleEvent(Event::Type event) override;
|
|
||||||
|
|
||||||
void drawWidget(bool hilite) override;
|
void drawWidget(bool hilite) override;
|
||||||
|
|
||||||
int valueToPos(int value);
|
uInt32 valueToPos(uInt32 value);
|
||||||
int posToValue(int pos);
|
uInt32 posToValue(uInt32 pos);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _value, _stepValue__;
|
uInt32 _value;
|
||||||
int _valueMin, _valueMax;
|
uInt32 _valueMin, _valueMax;
|
||||||
bool _isDragging;
|
bool _isDragging;
|
||||||
int _labelWidth;
|
uInt32 _labelWidth;
|
||||||
|
|
||||||
IntArray _stepValue;
|
uIntArray _stepValue;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,8 +22,37 @@
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
TimeMachine::TimeMachine(OSystem& osystem)
|
TimeMachine::TimeMachine(OSystem& osystem)
|
||||||
: DialogContainer(osystem)
|
: DialogContainer(osystem),
|
||||||
|
myWidth(FrameBuffer::kFBMinW)
|
||||||
{
|
{
|
||||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this,
|
myBaseDialog = new TimeMachineDialog(myOSystem, *this, myWidth);
|
||||||
FrameBuffer::kFBMinW, FrameBuffer::kFBMinH);
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
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);
|
TimeMachine(OSystem& osystem);
|
||||||
virtual ~TimeMachine() = default;
|
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:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
TimeMachine() = delete;
|
TimeMachine() = delete;
|
||||||
|
|
|
@ -36,7 +36,7 @@ using Common::Base;
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
int max_w, int max_h)
|
int width)
|
||||||
: Dialog(osystem, parent)
|
: Dialog(osystem, parent)
|
||||||
{
|
{
|
||||||
const int BUTTON_W = 16, BUTTON_H = 14;
|
const int BUTTON_W = 16, BUTTON_H = 14;
|
||||||
|
@ -75,23 +75,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
0b0110000110000110,
|
0b0110000110000110,
|
||||||
0
|
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] =
|
static uInt32 REWIND_1[BUTTON_H] =
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
@ -126,23 +109,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
0b0011100011000000,
|
0b0011100011000000,
|
||||||
0
|
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] =
|
static uInt32 UNWIND_ALL[BUTTON_H] =
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
@ -170,7 +136,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
|
|
||||||
// Set real dimensions
|
// 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;
|
_h = V_BORDER * 2 + rowHeight + buttonHeight + 2;
|
||||||
|
|
||||||
this->clearFlags(WIDGET_CLEARBG); // does only work combined with blending (0..100)!
|
this->clearFlags(WIDGET_CLEARBG); // does only work combined with blending (0..100)!
|
||||||
|
@ -189,7 +155,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
// Add timeline
|
// Add timeline
|
||||||
const uInt32 tl_h = myCurrentIdxWidget->getHeight() / 2,
|
const uInt32 tl_h = myCurrentIdxWidget->getHeight() / 2,
|
||||||
tl_x = xpos + myCurrentIdxWidget->getWidth() + 8,
|
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;
|
tl_w = myLastIdxWidget->getAbsX() - tl_x - 8;
|
||||||
myTimeline = new TimeLineWidget(this, font, tl_x, tl_y, tl_w, tl_h, "", 0, kTimeline);
|
myTimeline = new TimeLineWidget(this, font, tl_x, tl_y, tl_w, tl_h, "", 0, kTimeline);
|
||||||
myTimeline->setMinValue(0);
|
myTimeline->setMinValue(0);
|
||||||
|
@ -208,10 +174,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
BUTTON_W, BUTTON_H, kRewindAll);
|
BUTTON_W, BUTTON_H, kRewindAll);
|
||||||
xpos += buttonWidth + BUTTON_GAP;
|
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,
|
myRewind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_1,
|
||||||
BUTTON_W, BUTTON_H, kRewind1);
|
BUTTON_W, BUTTON_H, kRewind1);
|
||||||
xpos += buttonWidth + BUTTON_GAP*2;
|
xpos += buttonWidth + BUTTON_GAP*2;
|
||||||
|
@ -224,10 +186,6 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
BUTTON_W, BUTTON_H, kUnwind1);
|
BUTTON_W, BUTTON_H, kUnwind1);
|
||||||
xpos += buttonWidth + BUTTON_GAP;
|
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,
|
myUnwindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_ALL,
|
||||||
BUTTON_W, BUTTON_H, kUnwindAll);
|
BUTTON_W, BUTTON_H, kUnwindAll);
|
||||||
xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3;
|
xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3;
|
||||||
|
@ -254,14 +212,15 @@ void TimeMachineDialog::loadConfig()
|
||||||
IntArray cycles = r.cyclesList();
|
IntArray cycles = r.cyclesList();
|
||||||
|
|
||||||
// Set range and intervals for timeline
|
// 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);
|
myTimeline->setStepValues(cycles);
|
||||||
|
|
||||||
// Enable blending (only once is necessary)
|
// Enable blending (only once is necessary)
|
||||||
if(!surface().attributes().blending)
|
if(!surface().attributes().blending)
|
||||||
{
|
{
|
||||||
surface().attributes().blending = true;
|
surface().attributes().blending = true;
|
||||||
surface().attributes().blendalpha = 80;
|
surface().attributes().blendalpha = 92;
|
||||||
surface().applyAttributes();
|
surface().applyAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,11 +320,11 @@ string TimeMachineDialog::getTimeString(uInt64 cycles)
|
||||||
const Int32 PAL_FREQ = 1182298; // ~76*312*50
|
const Int32 PAL_FREQ = 1182298; // ~76*312*50
|
||||||
const Int32 freq = isNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second
|
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);
|
cycles -= minutes * (freq * 60);
|
||||||
uInt32 seconds = cycles / freq;
|
uInt32 seconds = uInt32(cycles / freq);
|
||||||
cycles -= seconds * freq;
|
cycles -= seconds * freq;
|
||||||
uInt32 frames = cycles / (scanlines * 76);
|
uInt32 frames = uInt32(cycles / (scanlines * 76));
|
||||||
|
|
||||||
stringstream time;
|
stringstream time;
|
||||||
time << Common::Base::toString(minutes, Common::Base::F_10_02) << ":";
|
time << Common::Base::toString(minutes, Common::Base::F_10_02) << ":";
|
||||||
|
@ -395,6 +354,7 @@ void TimeMachineDialog::handleWinds(Int32 numWinds)
|
||||||
myMessageWidget->setLabel((numWinds < 0 ? "(-" : "(+") + message + ")");
|
myMessageWidget->setLabel((numWinds < 0 ? "(-" : "(+") + message + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update time
|
// Update time
|
||||||
myCurrentTimeWidget->setLabel(getTimeString(r.getCurrentCycles() - r.getFirstCycles()));
|
myCurrentTimeWidget->setLabel(getTimeString(r.getCurrentCycles() - r.getFirstCycles()));
|
||||||
myLastTimeWidget->setLabel(getTimeString(r.getLastCycles() - r.getFirstCycles()));
|
myLastTimeWidget->setLabel(getTimeString(r.getLastCycles() - r.getFirstCycles()));
|
||||||
|
@ -404,9 +364,7 @@ void TimeMachineDialog::handleWinds(Int32 numWinds)
|
||||||
myLastIdxWidget->setValue(r.getLastIdx());
|
myLastIdxWidget->setValue(r.getLastIdx());
|
||||||
// Enable/disable buttons
|
// Enable/disable buttons
|
||||||
myRewindAllWidget->setEnabled(!r.atFirst());
|
myRewindAllWidget->setEnabled(!r.atFirst());
|
||||||
myRewind10Widget->setEnabled(!r.atFirst());
|
|
||||||
myRewind1Widget->setEnabled(!r.atFirst());
|
myRewind1Widget->setEnabled(!r.atFirst());
|
||||||
myUnwindAllWidget->setEnabled(!r.atLast());
|
myUnwindAllWidget->setEnabled(!r.atLast());
|
||||||
myUnwind10Widget->setEnabled(!r.atLast());
|
|
||||||
myUnwind1Widget->setEnabled(!r.atLast());
|
myUnwind1Widget->setEnabled(!r.atLast());
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ class TimeLineWidget;
|
||||||
class TimeMachineDialog : public Dialog
|
class TimeMachineDialog : public Dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int max_w, int max_h);
|
TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int width);
|
||||||
virtual ~TimeMachineDialog() = default;
|
virtual ~TimeMachineDialog() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -61,10 +61,8 @@ class TimeMachineDialog : public Dialog
|
||||||
|
|
||||||
ButtonWidget* myPlayWidget;
|
ButtonWidget* myPlayWidget;
|
||||||
ButtonWidget* myRewindAllWidget;
|
ButtonWidget* myRewindAllWidget;
|
||||||
ButtonWidget* myRewind10Widget;
|
|
||||||
ButtonWidget* myRewind1Widget;
|
ButtonWidget* myRewind1Widget;
|
||||||
ButtonWidget* myUnwind1Widget;
|
ButtonWidget* myUnwind1Widget;
|
||||||
ButtonWidget* myUnwind10Widget;
|
|
||||||
ButtonWidget* myUnwindAllWidget;
|
ButtonWidget* myUnwindAllWidget;
|
||||||
|
|
||||||
StaticTextWidget* myCurrentTimeWidget;
|
StaticTextWidget* myCurrentTimeWidget;
|
||||||
|
|
|
@ -390,7 +390,6 @@ void VideoDialog::saveConfig()
|
||||||
// TIA Filter
|
// TIA Filter
|
||||||
instance().settings().setValue("tia.zoom",
|
instance().settings().setValue("tia.zoom",
|
||||||
myTIAZoom->getSelectedTag().toString());
|
myTIAZoom->getSelectedTag().toString());
|
||||||
instance().frameBuffer().setZoomMode(instance().settings().getInt("tia.zoom"));
|
|
||||||
|
|
||||||
// TIA Palette
|
// TIA Palette
|
||||||
instance().settings().setValue("palette",
|
instance().settings().setValue("palette",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* Localized versions of Info.plist keys */
|
/* Localized versions of Info.plist keys */
|
||||||
|
|
||||||
CFBundleName = "Stella";
|
CFBundleName = "Stella";
|
||||||
CFBundleShortVersionString = "Stella version 5.0.2";
|
CFBundleShortVersionString = "Stella version 5.1";
|
||||||
CFBundleGetInfoString = "Stella version 5.0.2";
|
CFBundleGetInfoString = "Stella version 5.1";
|
||||||
NSHumanReadableCopyright = "Stella MacOS X version by Stephen Anthony and Mark Grebe.";
|
NSHumanReadableCopyright = "Stella MacOS X version by Stephen Anthony and Mark Grebe.";
|
||||||
|
|
||||||
"Atari 2600 Cartridge File" = "Atari 2600 Cartridge File";
|
"Atari 2600 Cartridge File" = "Atari 2600 Cartridge File";
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>StLa</string>
|
<string>StLa</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>5.0.2</string>
|
<string>5.1</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSMinimumSystemVersionByArchitecture</key>
|
<key>LSMinimumSystemVersionByArchitecture</key>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
%define name stella
|
%define name stella
|
||||||
%define version 5.0.2
|
%define version 5.1
|
||||||
%define rel 1
|
%define rel 1
|
||||||
|
|
||||||
%define enable_sound 1
|
%define enable_sound 1
|
||||||
|
@ -101,6 +101,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version}
|
||||||
%_datadir/icons/large/%{name}.png
|
%_datadir/icons/large/%{name}.png
|
||||||
|
|
||||||
%changelog
|
%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
|
* Sun Aug 20 2017 Stephen Anthony <stephena@users.sf.net> 5.0.2-1
|
||||||
- Version 5.0.2 release
|
- Version 5.0.2 release
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ IDI_ICON ICON "stella.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 5,0,2,0
|
FILEVERSION 5,1,0,0
|
||||||
PRODUCTVERSION 5,0,2,0
|
PRODUCTVERSION 5,1,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 (https://stella-emu.github.io)"
|
VALUE "CompanyName", "The Stella Team (https://stella-emu.github.io)"
|
||||||
VALUE "FileDescription", "Stella"
|
VALUE "FileDescription", "Stella"
|
||||||
VALUE "FileVersion", "5.0.2"
|
VALUE "FileVersion", "5.1"
|
||||||
VALUE "InternalName", "Stella"
|
VALUE "InternalName", "Stella"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 1995-2018 The Stella Team"
|
VALUE "LegalCopyright", "Copyright (C) 1995-2018 The Stella Team"
|
||||||
VALUE "OriginalFilename", "Stella.exe"
|
VALUE "OriginalFilename", "Stella.exe"
|
||||||
VALUE "ProductName", "Stella"
|
VALUE "ProductName", "Stella"
|
||||||
VALUE "ProductVersion", "5.0.2"
|
VALUE "ProductVersion", "5.1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Reference in New Issue