Merge branch 'master' into feature/precise-audio

This commit is contained in:
Christian Speckner 2018-01-29 21:18:36 +01:00
commit 89f3f4c9b8
112 changed files with 2278 additions and 1851 deletions

View File

@ -69,7 +69,8 @@
* Fixed swapped ports being displayed wrong in System Logs and debugger. * Fixed swapped ports being displayed wrong in System Logs and debugger.
* Added options to erase the AtariVox/Savekey flash memory, either for * Added options to erase the AtariVox/Savekey flash memory, either for
all ROMs or only the current one. 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 * Moved various developer related settings in new Developer Settings
dialog. These settings now come in two groups (player/developer) and dialog. These settings now come in two groups (player/developer) and

View File

@ -56,7 +56,7 @@ endif
ifdef CLANG_WARNINGS ifdef CLANG_WARNINGS
CXXFLAGS+= -Weverything -Wno-c++17-extensions -Wno-c++98-compat -Wno-c++98-compat-pedantic \ CXXFLAGS+= -Weverything -Wno-c++17-extensions -Wno-c++98-compat -Wno-c++98-compat-pedantic \
-Wno-double-promotion -Wno-switch-enum -Wno-conversion -Wno-covered-switch-default \ -Wno-double-promotion -Wno-switch-enum -Wno-conversion -Wno-covered-switch-default \
-Wno-inconsistent-missing-destructor-override \ -Wno-inconsistent-missing-destructor-override -Wno-float-equal \
-Wno-exit-time-destructors -Wno-global-constructors -Wno-weak-vtables \ -Wno-exit-time-destructors -Wno-global-constructors -Wno-weak-vtables \
-Wno-four-char-constants -Wno-padded -Wno-four-char-constants -Wno-padded
endif endif

View File

@ -268,7 +268,7 @@
joysticks or mouse</li> joysticks or mouse</li>
<li>Emulates the Sega Genesis Controller using your computer's keyboard, <li>Emulates the Sega Genesis Controller using your computer's keyboard,
joysticks or mouse</li> joysticks or mouse</li>
<li>Emulates CX22/CX80 style trakballs and Amiga/Atari Mouse using your <li>Emulates CX22/CX80 style trackballs and Amiga/Atari Mouse using your
computer's mouse</li> computer's mouse</li>
<li>Emulates <a href="http://en.wikipedia.org/wiki/CompuMate">Spectravideo CompuMate</a> system using your computer's keyboard, <li>Emulates <a href="http://en.wikipedia.org/wiki/CompuMate">Spectravideo CompuMate</a> system using your computer's keyboard,
including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to
@ -645,8 +645,8 @@
<tr> <tr>
<td>Enter/exit options mode</td> <td>Enter/exit options mode</td>
<td>Tab</td> <td>Tab/Escape</td>
<td>Tab</td> <td>Tab/Escape</td>
</tr> </tr>
<tr> <tr>
@ -1745,12 +1745,12 @@
<td> &#x2713;</td> <td> &#x2713;</td>
</tr> </tr>
<tr> <tr>
<th> Trakball/Mouse</th> <th> Trackball/Mouse</th>
<td> &#x2715;</td> <td> &#x2715;</td>
<td> &#x2715;</td> <td> &#x2715;</td>
<td> &#x2713;</td> <td> &#x2713;</td>
<td> &#x2713; (axis ignored)</td> <td> &#x2713; (axis ignored)</td>
<td> &#x2715;</td> <td> &#x2713;</td>
</tr> </tr>
<tr> <tr>
<th> CompuMate</th> <th> CompuMate</th>
@ -2103,7 +2103,7 @@
<td><pre>-usemouse &lt;always|analog|never&gt;</pre></td> <td><pre>-usemouse &lt;always|analog|never&gt;</pre></td>
<td>Use mouse as a controller as specified by ROM properties in specific case. <td>Use mouse as a controller as specified by ROM properties in specific case.
Always and never are self-explanatory, analog means only for analog-type devices Always and never are self-explanatory, analog means only for analog-type devices
(paddles, trakball, etc.).</td> (paddles, trackball, etc.).</td>
</tr> </tr>
<tr> <tr>
@ -2995,8 +2995,9 @@
<h2><b><a name="Adaptor">Stelladaptor/2600-daptor Support</a></b></h2> <h2><b><a name="Adaptor">Stelladaptor/2600-daptor Support</a></b></h2>
<blockquote> <blockquote>
<p>Stella supports real Atari 2600 joysticks, paddles and driving controllers <p>Stella supports real Atari 2600 joysticks, paddles, driving controllers
using the <a href="http://www.grandideastudio.com/portfolio/stelladaptor-2600">Stelladaptor</a> and and trackballs (CX22/CX80 'Trak-Ball', Atari and Amiga mouse) using the
<a href="http://www.grandideastudio.com/portfolio/stelladaptor-2600">Stelladaptor</a> and
<a href="http://2600-daptor.com">2600-daptor</a> devices.</p> <a href="http://2600-daptor.com">2600-daptor</a> devices.</p>
<p>Stella can use up to <b>two</b> adaptors; any extra ones are ignored. <p>Stella can use up to <b>two</b> adaptors; any extra ones are ignored.
@ -3190,8 +3191,7 @@
going back further in time. To reach the horizon, save states going back further in time. To reach the horizon, save states
will be compressed (*). This means that more and more intermediate will be compressed (*). This means that more and more intermediate
states will be removed and the interval between save states states will be removed and the interval between save states
becomes larger the further they are back in time. The very first becomes larger the further they are back in time.<br>
save state will not be removed.<br>
(*) Compresion only works if 'Uncompressed size' is smaller than (*) Compresion only works if 'Uncompressed size' is smaller than
'Buffer size'. 'Buffer size'.
</td> </td>

View File

@ -33,46 +33,48 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent, CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font) const GUI::Font& font)
: Dialog(osystem, parent) : Dialog(osystem, parent, font, "Cheat codes")
{ {
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth(), fontWidth = font.getMaxCharWidth(),
buttonWidth = font.getStringWidth("Defaults") + 20, buttonWidth = font.getStringWidth("Defaults") + 20,
buttonHeight = font.getLineHeight() + 4; buttonHeight = font.getLineHeight() + 4;
const int HBORDER = 10;
const int VBORDER = 10 + _th;
int xpos, ypos; int xpos, ypos;
WidgetArray wid; WidgetArray wid;
ButtonWidget* b; ButtonWidget* b;
// Set real dimensions // Set real dimensions
_w = 46 * fontWidth + 10; _w = 45 * fontWidth + HBORDER * 2;
_h = 11 * (lineHeight + 4) + 10; _h = 11 * (lineHeight + 4) + VBORDER;
// List of cheats, with checkboxes to enable/disable // List of cheats, with checkboxes to enable/disable
xpos = 10; ypos = 10; xpos = HBORDER; ypos = VBORDER;
myCheatList = myCheatList =
new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - 25, new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - HBORDER * 2 - 8,
_h - 2*buttonHeight - 10); _h - 2*buttonHeight - VBORDER);
myCheatList->setEditable(false); myCheatList->setEditable(false);
wid.push_back(myCheatList); wid.push_back(myCheatList);
xpos += myCheatList->getWidth() + 5; ypos = 15; xpos += myCheatList->getWidth() + 8; ypos = VBORDER;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Add" + ELLIPSIS, kAddCheatCmd); "Add" + ELLIPSIS, kAddCheatCmd);
wid.push_back(b); wid.push_back(b);
ypos += lineHeight + 10; ypos += lineHeight + 8;
myEditButton = myEditButton =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Edit" + ELLIPSIS, kEditCheatCmd); "Edit" + ELLIPSIS, kEditCheatCmd);
wid.push_back(myEditButton); wid.push_back(myEditButton);
ypos += lineHeight + 10; ypos += lineHeight + 8;
myRemoveButton = myRemoveButton =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Remove", kRemCheatCmd); "Remove", kRemCheatCmd);
wid.push_back(myRemoveButton); wid.push_back(myRemoveButton);
ypos += lineHeight + 10; ypos += lineHeight + 8 * 3;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"One shot" + ELLIPSIS, kAddOneShotCmd); "One shot" + ELLIPSIS, kAddOneShotCmd);
@ -82,7 +84,7 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
StringList labels; StringList labels;
labels.push_back("Name "); labels.push_back("Name ");
labels.push_back("Code (hex) "); labels.push_back("Code (hex) ");
myCheatInput = make_unique<InputTextDialog>(this, font, labels); myCheatInput = make_unique<InputTextDialog>(this, font, labels, "Cheat code");
myCheatInput->setTarget(this); myCheatInput->setTarget(this);
// Add filtering for each textfield // Add filtering for each textfield
@ -154,7 +156,7 @@ void CheatCodeDialog::addCheat()
myCheatInput->show(); // Center input dialog over entire screen myCheatInput->show(); // Center input dialog over entire screen
myCheatInput->setText("", 0); myCheatInput->setText("", 0);
myCheatInput->setText("", 1); myCheatInput->setText("", 1);
myCheatInput->setTitle(""); myCheatInput->setMessage("");
myCheatInput->setFocus(0); myCheatInput->setFocus(0);
myCheatInput->setEmitSignal(kCheatAdded); myCheatInput->setEmitSignal(kCheatAdded);
} }
@ -173,7 +175,7 @@ void CheatCodeDialog::editCheat()
myCheatInput->show(); // Center input dialog over entire screen myCheatInput->show(); // Center input dialog over entire screen
myCheatInput->setText(name, 0); myCheatInput->setText(name, 0);
myCheatInput->setText(code, 1); myCheatInput->setText(code, 1);
myCheatInput->setTitle(""); myCheatInput->setMessage("");
myCheatInput->setFocus(1); myCheatInput->setFocus(1);
myCheatInput->setEmitSignal(kCheatEdited); myCheatInput->setEmitSignal(kCheatEdited);
} }
@ -191,7 +193,7 @@ void CheatCodeDialog::addOneShotCheat()
myCheatInput->show(); // Center input dialog over entire screen myCheatInput->show(); // Center input dialog over entire screen
myCheatInput->setText("One-shot cheat", 0); myCheatInput->setText("One-shot cheat", 0);
myCheatInput->setText("", 1); myCheatInput->setText("", 1);
myCheatInput->setTitle(""); myCheatInput->setMessage("");
myCheatInput->setFocus(1); myCheatInput->setFocus(1);
myCheatInput->setEmitSignal(kOneShotCheatAdded); myCheatInput->setEmitSignal(kOneShotCheatAdded);
} }
@ -234,7 +236,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
loadConfig(); // show changes onscreen loadConfig(); // show changes onscreen
} }
else else
myCheatInput->setTitle("Invalid code"); myCheatInput->setMessage("Invalid code");
break; break;
} }
@ -251,7 +253,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
loadConfig(); // show changes onscreen loadConfig(); // show changes onscreen
} }
else else
myCheatInput->setTitle("Invalid code"); myCheatInput->setMessage("Invalid code");
break; break;
} }
@ -273,7 +275,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
instance().cheat().addOneShot(name, code); instance().cheat().addOneShot(name, code);
} }
else else
myCheatInput->setTitle("Invalid code"); myCheatInput->setMessage("Invalid code");
break; break;
} }

View File

@ -68,10 +68,14 @@ string Base::toString(int value, Common::Base::Format outputBase)
std::snprintf(vToS_buf, 6, "%5d", value); std::snprintf(vToS_buf, 6, "%5d", value);
break; break;
case Base::F_10_2: // base 10: 2 digits case Base::F_10_02: // base 10: 2 digits (with leading zero)
std::snprintf(vToS_buf, 3, "%02d", value); std::snprintf(vToS_buf, 3, "%02d", value);
break; break;
case Base::F_10_4: // base 10: 4 digits
std::snprintf(vToS_buf, 5, "%4d", value);
break;
case Base::F_16_1: // base 16: 1 byte wide case Base::F_16_1: // base 16: 1 byte wide
std::snprintf(vToS_buf, 2, myFmt[0], value); std::snprintf(vToS_buf, 2, myFmt[0], value);
break; break;

View File

@ -47,7 +47,8 @@ class Base
F_16_4, // base 16: 4 bytes wide F_16_4, // base 16: 4 bytes wide
F_16_8, // base 16: 8 bytes wide F_16_8, // base 16: 8 bytes wide
F_10, // base 10: 3 or 5 bytes (depending on value) F_10, // base 10: 3 or 5 bytes (depending on value)
F_10_2, // base 10: 2 digits F_10_02, // base 10: 02 digits
F_10_4, // base 10: 4 digits
F_2, // base 2: 8 or 16 bits (depending on value) F_2, // base 2: 8 or 16 bits (depending on value)
F_2_8, // base 2: 1 byte (8 bits) wide F_2_8, // base 2: 1 byte (8 bits) wide
F_2_16, // base 2: 2 bytes (16 bits) wide F_2_16, // base 2: 2 bytes (16 bits) wide

View File

@ -48,11 +48,11 @@ class FrameBufferSDL2 : public FrameBuffer
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
/** /**
Updates window title Updates window title.
@param title The title of the application / window @param title The title of the application / window
*/ */
void setTitle(const string& title); void setTitle(const string& title) override;
/** /**
Shows or hides the cursor based on the given boolean value. Shows or hides the cursor based on the given boolean value.

View File

@ -129,6 +129,12 @@ class LinkedObjectPool
*/ */
const_iter next(const_iter i) const { return std::next(i, 1); } const_iter next(const_iter i) const { return std::next(i, 1); }
/**
Canonical iterators from C++ STL.
*/
const_iter cbegin() const { return myList.cbegin(); }
const_iter cend() const { return myList.cend(); }
/** /**
Answer whether 'current' is at the specified iterator. Answer whether 'current' is at the specified iterator.
*/ */

View File

@ -42,7 +42,7 @@ void RewindManager::setup()
mySize = myOSystem.settings().getInt(prefix + "tm.size"); mySize = myOSystem.settings().getInt(prefix + "tm.size");
if(mySize != myStateList.capacity()) if(mySize != myStateList.capacity())
myStateList.resize(mySize); resize(mySize);
myUncompressed = myOSystem.settings().getInt(prefix + "tm.uncompressed"); myUncompressed = myOSystem.settings().getInt(prefix + "tm.uncompressed");
@ -56,7 +56,7 @@ void RewindManager::setup()
if(HOR_SETTINGS[i] == myOSystem.settings().getString(prefix + "tm.horizon")) if(HOR_SETTINGS[i] == myOSystem.settings().getString(prefix + "tm.horizon"))
myHorizon = HORIZON_CYCLES[i]; myHorizon = HORIZON_CYCLES[i];
// calc interval growth factor // calc interval growth factor for compression
// this factor defines the backward horizon // this factor defines the backward horizon
const double MAX_FACTOR = 1E8; const double MAX_FACTOR = 1E8;
double minFactor = 0, maxFactor = MAX_FACTOR; double minFactor = 0, maxFactor = MAX_FACTOR;
@ -71,8 +71,8 @@ void RewindManager::setup()
// horizon not reachable? // horizon not reachable?
if(myFactor == MAX_FACTOR) if(myFactor == MAX_FACTOR)
break; break;
// sum up interval cycles (first and last state are not compressed) // sum up interval cycles (first state is not compressed)
for(uInt32 i = myUncompressed + 1; i < mySize - 1; ++i) for(uInt32 i = myUncompressed + 1; i < mySize; ++i)
{ {
interval *= myFactor; interval *= myFactor;
cycleSum += interval; cycleSum += interval;
@ -88,7 +88,6 @@ void RewindManager::setup()
else else
maxFactor = myFactor; maxFactor = myFactor;
} }
//cerr << "factor " << myFactor << endl;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -138,7 +137,7 @@ bool RewindManager::addState(const string& message, bool timeMachine)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 RewindManager::rewindState(uInt32 numStates) uInt32 RewindManager::rewindStates(uInt32 numStates)
{ {
uInt64 startCycles = myOSystem.console().tia().cycles(); uInt64 startCycles = myOSystem.console().tia().cycles();
uInt32 i; uInt32 i;
@ -177,7 +176,7 @@ uInt32 RewindManager::rewindState(uInt32 numStates)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 RewindManager::unwindState(uInt32 numStates) uInt32 RewindManager::unwindStates(uInt32 numStates)
{ {
uInt64 startCycles = myOSystem.console().tia().cycles(); uInt64 startCycles = myOSystem.console().tia().cycles();
uInt32 i; uInt32 i;
@ -210,44 +209,48 @@ uInt32 RewindManager::unwindState(uInt32 numStates)
return i; return i;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 RewindManager::windStates(uInt32 numStates, bool unwind)
{
if(unwind)
return unwindStates(numStates);
else
return rewindStates(numStates);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RewindManager::compressStates() void RewindManager::compressStates()
{ {
double expectedCycles = myInterval * myFactor * (1 + myFactor); double expectedCycles = myInterval * myFactor * (1 + myFactor);
double maxError = 1.5; double maxError = 1.5;
uInt32 idx = myStateList.size() - 2; uInt32 idx = myStateList.size() - 2;
//uInt32 removeIdx = 0;
// in case maxError is <= 1.5 remove first state by default: // in case maxError is <= 1.5 remove first state by default:
Common::LinkedObjectPool<RewindState>::const_iter removeIter = myStateList.first(); Common::LinkedObjectPool<RewindState>::const_iter removeIter = myStateList.first();
if(myUncompressed < mySize) /*if(myUncompressed < mySize)
// if compression is enabled, the first but one state is removed by default: // if compression is enabled, the first but one state is removed by default:
removeIter++; removeIter++;*/
//cerr << "idx: " << idx << endl;
// iterate from last but one to first but one // iterate from last but one to first but one
for(auto it = myStateList.previous(myStateList.last()); it != myStateList.first(); --it) for(auto it = myStateList.previous(myStateList.last()); it != myStateList.first(); --it)
{ {
if(idx < mySize - myUncompressed) if(idx < mySize - myUncompressed)
{ {
//cerr << *it << endl << endl; // debug code
expectedCycles *= myFactor; expectedCycles *= myFactor;
uInt64 prevCycles = myStateList.previous(it)->cycles; uInt64 prevCycles = myStateList.previous(it)->cycles;
uInt64 nextCycles = myStateList.next(it)->cycles; uInt64 nextCycles = myStateList.next(it)->cycles;
double error = expectedCycles / (nextCycles - prevCycles); double error = expectedCycles / (nextCycles - prevCycles);
//cerr << "prevCycles: " << prevCycles << ", nextCycles: " << nextCycles << ", error: " << error << endl;
if(error > maxError) if(error > maxError)
{ {
maxError = error; maxError = error;
removeIter = it; removeIter = it;
//removeIdx = idx;
} }
} }
--idx; --idx;
} }
myStateList.remove(removeIter); // remove myStateList.remove(removeIter); // remove
//cerr << "remove " << removeIdx << endl;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -295,7 +298,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 < 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];
@ -306,14 +309,14 @@ string RewindManager::getUnitString(Int64 cycles)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 RewindManager::getFirstCycles() uInt32 RewindManager::getFirstCycles() const
{ {
// TODO: check if valid // TODO: check if valid
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.first())->cycles; return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.first())->cycles;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 RewindManager::getCurrentCycles() uInt32 RewindManager::getCurrentCycles() const
{ {
if(myStateList.currentIsValid()) if(myStateList.currentIsValid())
return myStateList.current().cycles; return myStateList.current().cycles;
@ -322,9 +325,20 @@ uInt32 RewindManager::getCurrentCycles()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 RewindManager::getLastCycles() uInt32 RewindManager::getLastCycles() const
{ {
// TODO: check if valid // TODO: check if valid
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.last())->cycles; return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.last())->cycles;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IntArray RewindManager::cyclesList() const
{
IntArray arr;
uInt64 firstCycle = getFirstCycles();
for(auto it = myStateList.cbegin(); it != myStateList.cend(); ++it)
arr.push_back(uInt32(it->cycles - firstCycle));
return arr;
}

View File

@ -38,6 +38,9 @@ class StateManager;
to the end of the list (aka, all future states) are removed, and the internal to the end of the list (aka, all future states) are removed, and the internal
iterator moves to the insertion point of the data (the end of the list). iterator moves to the insertion point of the data (the end of the list).
If the list is full, states are either removed at the beginning (compression
off) or at selective positions (compression on).
@author Stephen Anthony @author Stephen Anthony
*/ */
class RewindManager class RewindManager
@ -106,22 +109,32 @@ class RewindManager
bool addState(const string& message, bool timeMachine = false); bool addState(const string& message, bool timeMachine = false);
/** /**
Rewind one level of the state list, and display the message associated Rewind numStates levels of the state list, and display the message associated
with that state. with that state.
@param numStates Number of states to rewind @param numStates Number of states to rewind
@return Number of states to rewinded @return Number of states to rewinded
*/ */
uInt32 rewindState(uInt32 numStates = 1); uInt32 rewindStates(uInt32 numStates = 1);
/** /**
Unwind one level of the state list, and display the message associated Unwind numStates levels of the state list, and display the message associated
with that state. with that state.
@param numStates Number of states to unwind @param numStates Number of states to unwind
@return Number of states to unwinded @return Number of states to unwinded
*/ */
uInt32 unwindState(uInt32 numStates = 1); uInt32 unwindStates(uInt32 numStates = 1);
/**
Rewind/unwind numStates levels of the state list, and display the message associated
with that state.
@param numStates Number of states to wind
@param unwind unwind or rewind
@return Number of states to winded
*/
uInt32 windStates(uInt32 numStates, bool unwind);
bool atFirst() const { return myStateList.atFirst(); } bool atFirst() const { return myStateList.atFirst(); }
bool atLast() const { return myStateList.atLast(); } bool atLast() const { return myStateList.atLast(); }
@ -136,9 +149,15 @@ class RewindManager
uInt32 getCurrentIdx() { return myStateList.currentIdx(); } uInt32 getCurrentIdx() { return myStateList.currentIdx(); }
uInt32 getLastIdx() { return myStateList.size(); } uInt32 getLastIdx() { return myStateList.size(); }
uInt32 getFirstCycles(); uInt32 getFirstCycles() const;
uInt32 getCurrentCycles(); uInt32 getCurrentCycles() const;
uInt32 getLastCycles(); uInt32 getLastCycles() const;
/**
Get a collection of cycle timestamps, offset from the first one in
the list. This also determines the number of states in the list.
*/
IntArray cyclesList() const;
private: private:
OSystem& myOSystem; OSystem& myOSystem;

View File

@ -44,6 +44,7 @@ class FixedStack
bool full() const { return _size >= CAPACITY; } bool full() const { return _size >= CAPACITY; }
T top() const { return _stack[_size - 1]; } T top() const { return _stack[_size - 1]; }
T get(uInt32 pos) { return _stack[pos]; };
void push(const T& x) { _stack[_size++] = x; } void push(const T& x) { _stack[_size++] = x; }
T pop() { return std::move(_stack[--_size]); } T pop() { return std::move(_stack[--_size]); }
uInt32 size() const { return _size; } uInt32 size() const { return _size; }

View File

@ -142,17 +142,35 @@ void StateManager::toggleTimeMachine()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool StateManager::rewindState(uInt32 numStates) bool StateManager::addExtraState(const string& message)
{ {
if(myActiveMode == Mode::TimeMachine)
{
RewindManager& r = myOSystem.state().rewindManager(); RewindManager& r = myOSystem.state().rewindManager();
return r.rewindState(numStates); return r.addState(message);
}
return false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool StateManager::unwindState(uInt32 numStates) bool StateManager::rewindStates(uInt32 numStates)
{ {
RewindManager& r = myOSystem.state().rewindManager(); RewindManager& r = myOSystem.state().rewindManager();
return r.unwindState(numStates); return r.rewindStates(numStates);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool StateManager::unwindStates(uInt32 numStates)
{
RewindManager& r = myOSystem.state().rewindManager();
return r.unwindStates(numStates);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool StateManager::windStates(uInt32 numStates, bool unwind)
{
RewindManager& r = myOSystem.state().rewindManager();
return r.windStates(numStates, unwind);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -72,14 +72,25 @@ class StateManager
void setRewindMode(Mode mode) { myActiveMode = mode; } void setRewindMode(Mode mode) { myActiveMode = mode; }
/** /**
Rewinds one state; this uses the RewindManager for its functionality. Optionally adds one extra state when entering the Time Machine dialog;
this uses the RewindManager for its functionality.
*/ */
bool rewindState(uInt32 numStates = 1); bool addExtraState(const string& message);
/** /**
Unwinds one state; this uses the RewindManager for its functionality. Rewinds states; this uses the RewindManager for its functionality.
*/ */
bool unwindState(uInt32 numStates = 1); bool rewindStates(uInt32 numStates = 1);
/**
Unwinds states; this uses the RewindManager for its functionality.
*/
bool unwindStates(uInt32 numStates = 1);
/**
Rewinds/unwinds states; this uses the RewindManager for its functionality.
*/
bool windStates(uInt32 numStates, bool unwind);
/** /**
Updates the state of the system based on the currently active mode. Updates the state of the system based on the currently active mode.

View File

@ -18,7 +18,7 @@
#ifndef VERSION_HXX #ifndef VERSION_HXX
#define VERSION_HXX #define VERSION_HXX
#define STELLA_VERSION "5.1_a2" #define STELLA_VERSION "5.1_b1"
#define STELLA_BUILD "3826" #define STELLA_BUILD "3826"
#endif #endif

View File

@ -538,7 +538,7 @@ uInt16 Debugger::windStates(uInt16 numStates, bool unwind, string& message)
unlockBankswitchState(); unlockBankswitchState();
uInt64 startCycles = myOSystem.console().tia().cycles(); uInt64 startCycles = myOSystem.console().tia().cycles();
uInt16 winds = unwind ? r.unwindState(numStates) : r.rewindState(numStates); uInt16 winds = r.windStates(numStates, unwind);
message = r.getUnitString(myOSystem.console().tia().cycles() - startCycles); message = r.getUnitString(myOSystem.console().tia().cycles() - startCycles);
lockBankswitchState(); lockBankswitchState();
@ -620,7 +620,8 @@ void Debugger::setStartState()
// Save initial state and add it to the rewind list (except when in currently rewinding) // Save initial state and add it to the rewind list (except when in currently rewinding)
RewindManager& r = myOSystem.state().rewindManager(); RewindManager& r = myOSystem.state().rewindManager();
// avoid invalidating future states when entering the debugger e.g. during rewind // avoid invalidating future states when entering the debugger e.g. during rewind
if(myOSystem.eventHandler().state() == EventHandlerState::EMULATION) if(r.atLast() && (myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE
|| myOSystem.state().mode() == StateManager::Mode::Off))
addState("enter debugger"); addState("enter debugger");
else else
updateRewindbuttons(r); updateRewindbuttons(r);
@ -783,6 +784,12 @@ void Debugger::unlockBankswitchState()
myConsole.cartridge().unlockBank(); myConsole.cartridge().unlockBank();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Debugger::canExit() const
{
return myDialogStack.top() == baseDialog();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Debugger::BuiltinFunction Debugger::ourBuiltinFunctions[NUM_BUILTIN_FUNCS] = { Debugger::BuiltinFunction Debugger::ourBuiltinFunctions[NUM_BUILTIN_FUNCS] = {
// left joystick: // left joystick:

View File

@ -240,6 +240,12 @@ class Debugger : public DialogContainer
void lockBankswitchState(); void lockBankswitchState();
void unlockBankswitchState(); void unlockBankswitchState();
/**
Answers whether the debugger can be exited. Currently this only
happens when no other dialogs are active.
*/
bool canExit() const;
private: private:
/** /**
Save state of each debugger subsystem and, by default, mark all Save state of each debugger subsystem and, by default, mark all

View File

@ -66,6 +66,7 @@ const DebuggerState& RiotDebug::getState()
myState.TIMINT = timint(); myState.TIMINT = timint();
myState.TIMCLKS = timClocks(); myState.TIMCLKS = timClocks();
myState.INTIMCLKS = intimClocks(); myState.INTIMCLKS = intimClocks();
myState.TIMDIV = timDivider();
return myState; return myState;
} }
@ -107,6 +108,7 @@ void RiotDebug::saveOldState()
myOldState.TIMINT = timint(); myOldState.TIMINT = timint();
myOldState.TIMCLKS = timClocks(); myOldState.TIMCLKS = timClocks();
myOldState.INTIMCLKS = intimClocks(); myOldState.INTIMCLKS = intimClocks();
myOldState.TIMDIV = timDivider();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -223,6 +225,12 @@ Int32 RiotDebug::intimClocks() const
return mySystem.m6532().intimClocks(); return mySystem.m6532().intimClocks();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 RiotDebug::timDivider() const
{
return mySystem.m6532().myDivider;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller& RiotDebug::controller(Controller::Jack jack) const Controller& RiotDebug::controller(Controller::Jack jack) const
{ {
@ -362,6 +370,7 @@ string RiotDebug::toString()
<< " 285/TIMINT=" << myDebugger.invIfChanged(state.TIMINT, oldstate.TIMINT) << " 285/TIMINT=" << myDebugger.invIfChanged(state.TIMINT, oldstate.TIMINT)
<< " Timer_Clocks=" << myDebugger.invIfChanged(state.TIMCLKS, oldstate.TIMCLKS) << " Timer_Clocks=" << myDebugger.invIfChanged(state.TIMCLKS, oldstate.TIMCLKS)
<< " INTIM_Clocks=" << myDebugger.invIfChanged(state.INTIMCLKS, oldstate.INTIMCLKS) << " INTIM_Clocks=" << myDebugger.invIfChanged(state.INTIMCLKS, oldstate.INTIMCLKS)
<< " Divider=" << myDebugger.invIfChanged(state.TIMDIV, oldstate.TIMDIV)
<< endl << endl
<< "Left/P0diff: " << diffP0String() << " Right/P1diff: " << diffP0String() << "Left/P0diff: " << diffP0String() << " Right/P1diff: " << diffP0String()

View File

@ -36,7 +36,7 @@ class RiotState : public DebuggerState
BoolArray swbcntBits; BoolArray swbcntBits;
uInt8 TIM1T, TIM8T, TIM64T, T1024T, INTIM, TIMINT; uInt8 TIM1T, TIM8T, TIM64T, T1024T, INTIM, TIMINT;
Int32 TIMCLKS, INTIMCLKS; Int32 TIMCLKS, INTIMCLKS, TIMDIV;
// These are actually from the TIA, but are I/O related // These are actually from the TIA, but are I/O related
uInt8 INPT0, INPT1, INPT2, INPT3, INPT4, INPT5; uInt8 INPT0, INPT1, INPT2, INPT3, INPT4, INPT5;
@ -74,6 +74,7 @@ class RiotDebug : public DebuggerSystem
uInt8 timint() const; uInt8 timint() const;
Int32 timClocks() const; Int32 timClocks() const;
Int32 intimClocks() const; Int32 intimClocks() const;
Int32 timDivider() const;
/* Controller ports */ /* Controller ports */
Controller& controller(Controller::Jack jack) const; Controller& controller(Controller::Jack jack) const;

View File

@ -78,7 +78,7 @@ int CartDebugWidget::addBaseInformation(int bytes, const string& manufacturer,
fwidth, lines * myLineHeight, false); fwidth, lines * myLineHeight, false);
myDesc->setEditable(false); myDesc->setEditable(false);
myDesc->setList(sl); myDesc->setList(sl);
addFocusWidget(myDesc);
y += myDesc->getHeight() + 4; y += myDesc->getHeight() + 4;
return y; return y;

View File

@ -50,8 +50,7 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
_opsWidget(nullptr), _opsWidget(nullptr),
_scrollBar(nullptr) _scrollBar(nullptr)
{ {
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | _flags = WIDGET_ENABLED | WIDGET_RETAIN_FOCUS | WIDGET_WANTS_RAWDATA;
WIDGET_WANTS_RAWDATA;
_editMode = false; _editMode = false;
// The item is selected, thus _bgcolor is used to draw the caret and // The item is selected, thus _bgcolor is used to draw the caret and
@ -250,6 +249,20 @@ void DataGridWidget::setRange(int lower, int upper)
_upperBound = std::min(1 << _bits, upper); _upperBound = std::min(1 << _bits, upper);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DataGridWidget::handleMouseEntered()
{
setFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DataGridWidget::handleMouseLeft()
{
clearFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DataGridWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) void DataGridWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
{ {
@ -582,25 +595,16 @@ void DataGridWidget::drawWidget(bool hilite)
FBSurface& s = _boss->dialog().surface(); FBSurface& s = _boss->dialog().surface();
int row, col; int row, col;
s.fillRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? _bgcolorhi : _bgcolor);
// Draw the internal grid and labels // Draw the internal grid and labels
int linewidth = _cols * _colWidth; int linewidth = _cols * _colWidth;
#ifndef FLAT_UI s.frameRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor);
for (row = 0; row <= _rows; row++)
s.hLine(_x, _y + (row * _rowHeight), _x + linewidth, kColor);
int lineheight = _rows * _rowHeight;
for (col = 0; col <= _cols; col++)
s.vLine(_x + (col * _colWidth), _y, _y + lineheight, kColor);
#else
s.frameRect(_x, _y, _w, _h, kColor);
for(row = 1; row <= _rows-1; row++) for(row = 1; row <= _rows-1; row++)
s.hLine(_x+1, _y + (row * _rowHeight), _x + linewidth-1, kBGColorLo); s.hLine(_x+1, _y + (row * _rowHeight), _x + linewidth-1, kBGColorLo);
int lineheight = _rows * _rowHeight; int lineheight = _rows * _rowHeight;
for(col = 1; col <= _cols-1; col++) for(col = 1; col <= _cols-1; col++)
s.vLine(_x + (col * _colWidth), _y+1, _y + lineheight-1, kBGColorLo); s.vLine(_x + (col * _colWidth), _y+1, _y + lineheight-1, kBGColorLo);
#endif
// Draw the list items // Draw the list items
for (row = 0; row < _rows; row++) for (row = 0; row < _rows; row++)

View File

@ -100,6 +100,8 @@ class DataGridWidget : public EditableWidget
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;
void handleMouseEntered() override;
void handleMouseLeft() override;
bool handleText(char text) override; bool handleText(char text) override;
bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyDown(StellaKey key, StellaMod mod) override;
bool handleKeyUp(StellaKey key, StellaMod mod) override; bool handleKeyUp(StellaKey key, StellaMod mod) override;

View File

@ -93,11 +93,39 @@ void DebuggerDialog::handleKeyDown(StellaKey key, StellaMod mod)
else if(key == KBDK_F12) else if(key == KBDK_F12)
{ {
instance().debugger().parser().run("savesnap"); instance().debugger().parser().run("savesnap");
return;
}
else if(StellaModTest::isAlt(mod) && !StellaModTest::isControl(mod))
{
switch(key)
{
case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states
if(StellaModTest::isShift(mod))
doRewind10();
else
doRewind();
return;
case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states
if(StellaModTest::isShift(mod))
doUnwind10();
else
doUnwind();
return;
case KBDK_DOWN: // Alt-down rewinds to start of list
doRewindAll();
return;
case KBDK_UP: // Alt-up rewinds to end of list
doUnwindAll();
return;
default:
break;
}
} }
else if(StellaModTest::isControl(mod)) else if(StellaModTest::isControl(mod))
{ {
switch(key) switch(key)
{ {
#if 0
case KBDK_R: case KBDK_R:
if(StellaModTest::isAlt(mod)) if(StellaModTest::isAlt(mod))
doRewindAll(); doRewindAll();
@ -105,7 +133,7 @@ void DebuggerDialog::handleKeyDown(StellaKey key, StellaMod mod)
doRewind10(); doRewind10();
else else
doRewind(); doRewind();
break; return;
case KBDK_Y: case KBDK_Y:
if(StellaModTest::isAlt(mod)) if(StellaModTest::isAlt(mod))
doUnwindAll(); doUnwindAll();
@ -113,19 +141,20 @@ void DebuggerDialog::handleKeyDown(StellaKey key, StellaMod mod)
doUnwind10(); doUnwind10();
else else
doUnwind(); doUnwind();
break; return;
#endif
case KBDK_S: case KBDK_S:
doStep(); doStep();
break; return;
case KBDK_T: case KBDK_T:
doTrace(); doTrace();
break; return;
case KBDK_L: case KBDK_L:
doScanlineAdvance(); doScanlineAdvance();
break; return;
case KBDK_F: case KBDK_F:
doAdvance(); doAdvance();
break; return;
default: default:
break; break;
} }
@ -322,7 +351,7 @@ void DebuggerDialog::createFont()
void DebuggerDialog::showFatalMessage(const string& msg) void DebuggerDialog::showFatalMessage(const string& msg)
{ {
myFatalError = make_unique<GUI::MessageBox>(this, *myLFont, msg, _w/2, _h/2, myFatalError = make_unique<GUI::MessageBox>(this, *myLFont, msg, _w/2, _h/2,
kDDExitFatalCmd, "Exit ROM", "Continue"); kDDExitFatalCmd, "Exit ROM", "Continue", "Fatal error");
myFatalError->show(); myFatalError->show();
} }
@ -353,15 +382,9 @@ void DebuggerDialog::addTabArea()
int tabID; int tabID;
// The Prompt/console tab // The Prompt/console tab
#ifndef FLAT_UI
tabID = myTab->addTab(" Prompt ");
myPrompt = new PromptWidget(myTab, *myNFont,
2, 2, widWidth, widHeight);
#else
tabID = myTab->addTab("Prompt"); tabID = myTab->addTab("Prompt");
myPrompt = new PromptWidget(myTab, *myNFont, myPrompt = new PromptWidget(myTab, *myNFont,
2, 2, widWidth - 4, widHeight); 2, 2, widWidth - 4, widHeight);
#endif
myTab->setParentWidget(tabID, myPrompt); myTab->setParentWidget(tabID, myPrompt);
addToFocusList(myPrompt->getFocusList(), myTab, tabID); addToFocusList(myPrompt->getFocusList(), myTab, tabID);
@ -448,24 +471,32 @@ void DebuggerDialog::addRomArea()
const GUI::Rect& r = getRomBounds(); const GUI::Rect& r = getRomBounds();
const int VBORDER = 4; const int VBORDER = 4;
const string ELLIPSIS = "\x1d"; const string ELLIPSIS = "\x1d";
WidgetArray wid1, wid2;
ButtonWidget* b;
int bwidth = myLFont->getStringWidth("Frame +1 "), int bwidth = myLFont->getStringWidth("Frame +1 "),
bheight = myLFont->getLineHeight() + 2; bheight = myLFont->getLineHeight() + 2;
int buttonX = r.right - bwidth - 5, buttonY = r.top + 5; int buttonX = r.right - bwidth - 5, buttonY = r.top + 5;
new ButtonWidget(this, *myLFont, buttonX, buttonY,
b = new ButtonWidget(this, *myLFont, buttonX, buttonY,
bwidth, bheight, "Step", kDDStepCmd); bwidth, bheight, "Step", kDDStepCmd);
wid2.push_back(b);
buttonY += bheight + 4; buttonY += bheight + 4;
new ButtonWidget(this, *myLFont, buttonX, buttonY, b = new ButtonWidget(this, *myLFont, buttonX, buttonY,
bwidth, bheight, "Trace", kDDTraceCmd); bwidth, bheight, "Trace", kDDTraceCmd);
wid2.push_back(b);
buttonY += bheight + 4; buttonY += bheight + 4;
new ButtonWidget(this, *myLFont, buttonX, buttonY, b = new ButtonWidget(this, *myLFont, buttonX, buttonY,
bwidth, bheight, "Scan +1", kDDSAdvCmd); bwidth, bheight, "Scan +1", kDDSAdvCmd);
wid2.push_back(b);
buttonY += bheight + 4; buttonY += bheight + 4;
new ButtonWidget(this, *myLFont, buttonX, buttonY, b = new ButtonWidget(this, *myLFont, buttonX, buttonY,
bwidth, bheight, "Frame +1", kDDAdvCmd); bwidth, bheight, "Frame +1", kDDAdvCmd);
wid2.push_back(b);
buttonY += bheight + 4; buttonY += bheight + 4;
new ButtonWidget(this, *myLFont, buttonX, buttonY, b = new ButtonWidget(this, *myLFont, buttonX, buttonY,
bwidth, bheight, "Exit", kDDExitCmd); bwidth, bheight, "Exit", kDDExitCmd);
wid2.push_back(b);
bwidth = bheight; // 7 + 12; bwidth = bheight; // 7 + 12;
bheight = bheight * 3 + 4 * 2; bheight = bheight * 3 + 4 * 2;
@ -475,7 +506,6 @@ void DebuggerDialog::addRomArea()
myRewindButton = myRewindButton =
new ButtonWidget(this, *myLFont, buttonX, buttonY, new ButtonWidget(this, *myLFont, buttonX, buttonY,
bwidth, bheight, LEFT_ARROW, 7, 11, kDDRewindCmd); bwidth, bheight, LEFT_ARROW, 7, 11, kDDRewindCmd);
myRewindButton->clearFlags(WIDGET_ENABLED); myRewindButton->clearFlags(WIDGET_ENABLED);
buttonY += bheight + 4; buttonY += bheight + 4;
@ -491,7 +521,11 @@ void DebuggerDialog::addRomArea()
bwidth = myLFont->getStringWidth("Options " + ELLIPSIS); bwidth = myLFont->getStringWidth("Options " + ELLIPSIS);
bheight = myLFont->getLineHeight() + 2; bheight = myLFont->getLineHeight() + 2;
new ButtonWidget(this, *myLFont, xpos, r.top + 5, bwidth, bheight, "Options" + ELLIPSIS, kDDOptionsCmd); b = new ButtonWidget(this, *myLFont, xpos, r.top + 5, bwidth, bheight,
"Options" + ELLIPSIS, kDDOptionsCmd);
wid1.push_back(b);
wid1.push_back(myRewindButton);
wid1.push_back(myUnwindButton);
DataGridOpsWidget* ops = new DataGridOpsWidget(this, *myLFont, xpos, ypos); DataGridOpsWidget* ops = new DataGridOpsWidget(this, *myLFont, xpos, ypos);
@ -500,6 +534,9 @@ void DebuggerDialog::addRomArea()
myCpu = new CpuWidget(this, *myLFont, *myNFont, xpos, ypos, max_w); myCpu = new CpuWidget(this, *myLFont, *myNFont, xpos, ypos, max_w);
addToFocusList(myCpu->getFocusList()); addToFocusList(myCpu->getFocusList());
addToFocusList(wid1);
addToFocusList(wid2);
xpos = r.left + 10; ypos += myCpu->getHeight() + 10; xpos = r.left + 10; ypos += myCpu->getHeight() + 10;
myRam = new RiotRamWidget(this, *myLFont, *myNFont, xpos, ypos, r.width() - 10); myRam = new RiotRamWidget(this, *myLFont, *myNFont, xpos, ypos, r.width() - 10);
addToFocusList(myRam->getFocusList()); addToFocusList(myRam->getFocusList());

View File

@ -96,12 +96,12 @@ void DelayQueueWidget::drawWidget(bool hilite)
w = _w, w = _w,
lineHeight = _font.getLineHeight(); lineHeight = _font.getLineHeight();
surface.frameRect(x, y, w, _h, kShadowColor); surface.frameRect(x, y, w, _h, kColor);
y += 1; y += 1;
x += 1; x += 1;
w -= 1; w -= 1;
surface.fillRect(x, y, w - 1, _h - 2, kBGColorHi); surface.fillRect(x, y, w - 1, _h - 2, kDlgColor);
y += 2; y += 2;
x += 2; x += 2;

View File

@ -32,15 +32,14 @@ PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font,
int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Paddles)"); int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Paddles)");
new StaticTextWidget(boss, font, xpos, ypos+2, lwidth, new StaticTextWidget(boss, font, xpos, ypos+2, lwidth,
fontHeight, label, TextAlign::Left); fontHeight, label);
ypos += lineHeight + 20; ypos += lineHeight + 20;
const string& p0string = leftport ? "P0 pot " : "P2 pot "; const string& p0string = leftport ? "P0 pot " : "P2 pot ";
const string& p1string = leftport ? "P1 pot " : "P3 pot "; const string& p1string = leftport ? "P1 pot " : "P3 pot ";
lwidth = font.getStringWidth("P3 pot: ");
myP0Resistance = myP0Resistance =
new SliderWidget(boss, font, xpos, ypos, 10*fontWidth, lineHeight, new SliderWidget(boss, font, xpos, ypos,
p0string, lwidth, kP0Changed); p0string, 0, kP0Changed);
myP0Resistance->setMinValue(0); myP0Resistance->setMinValue(0);
myP0Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE)); myP0Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE));
myP0Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100)); myP0Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100));
@ -53,8 +52,8 @@ PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font,
xpos = x; ypos += 2*lineHeight; xpos = x; ypos += 2*lineHeight;
myP1Resistance = myP1Resistance =
new SliderWidget(boss, font, xpos, ypos, 10*fontWidth, lineHeight, new SliderWidget(boss, font, xpos, ypos,
p1string, lwidth, kP1Changed); p1string, 0, kP1Changed);
myP1Resistance->setMinValue(0); myP1Resistance->setMinValue(0);
myP1Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE)); myP1Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE));
myP1Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100)); myP1Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100));

View File

@ -46,6 +46,7 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
const int bwidth = lfont.getStringWidth("Compare " + ELLIPSIS), const int bwidth = lfont.getStringWidth("Compare " + ELLIPSIS),
bheight = myLineHeight + 2; bheight = myLineHeight + 2;
const int VGAP = 4; const int VGAP = 4;
WidgetArray wid;
int ypos = y + myLineHeight; int ypos = y + myLineHeight;
@ -63,28 +64,35 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
myUndoButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, myUndoButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
"Undo", kUndoCmd); "Undo", kUndoCmd);
wid.push_back(myUndoButton);
myUndoButton->setTarget(this); myUndoButton->setTarget(this);
by += bheight + VGAP; by += bheight + VGAP;
myRevertButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, myRevertButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
"Revert", kRevertCmd); "Revert", kRevertCmd);
wid.push_back(myRevertButton);
myRevertButton->setTarget(this); myRevertButton->setTarget(this);
by += bheight + VGAP * 6; by += bheight + VGAP * 6;
mySearchButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, mySearchButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
"Search" + ELLIPSIS, kSearchCmd); "Search" + ELLIPSIS, kSearchCmd);
wid.push_back(mySearchButton);
mySearchButton->setTarget(this); mySearchButton->setTarget(this);
by += bheight + VGAP; by += bheight + VGAP;
myCompareButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, myCompareButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
"Compare" + ELLIPSIS, kCmpCmd); "Compare" + ELLIPSIS, kCmpCmd);
wid.push_back(myCompareButton);
myCompareButton->setTarget(this); myCompareButton->setTarget(this);
by += bheight + VGAP; by += bheight + VGAP;
myRestartButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, myRestartButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
"Reset", kRestartCmd); "Reset", kRestartCmd);
wid.push_back(myRestartButton);
myRestartButton->setTarget(this); myRestartButton->setTarget(this);
addToFocusList(wid);
// Labels for RAM grid // Labels for RAM grid
myRamStart = myRamStart =
new StaticTextWidget(_boss, lfont, xpos - _font.getStringWidth("xxxx"), new StaticTextWidget(_boss, lfont, xpos - _font.getStringWidth("xxxx"),
@ -146,8 +154,8 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
myLabel->setEditable(false, true); myLabel->setEditable(false, true);
// Inputbox which will pop up when searching RAM // Inputbox which will pop up when searching RAM
StringList labels = { "Search " }; StringList labels = { "Value" };
myInputBox = make_unique<InputTextDialog>(boss, lfont, nfont, labels); myInputBox = make_unique<InputTextDialog>(boss, lfont, nfont, labels, " ");
myInputBox->setTarget(this); myInputBox->setTarget(this);
// Start with these buttons disabled // Start with these buttons disabled
@ -247,7 +255,7 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{ {
const string& result = doSearch(myInputBox->getResult()); const string& result = doSearch(myInputBox->getResult());
if(result != "") if(result != "")
myInputBox->setTitle(result); myInputBox->setMessage(result);
else else
myInputBox->close(); myInputBox->close();
break; break;
@ -257,7 +265,7 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{ {
const string& result = doCompare(myInputBox->getResult()); const string& result = doCompare(myInputBox->getResult());
if(result != "") if(result != "")
myInputBox->setTitle(result); myInputBox->setMessage(result);
else else
myInputBox->close(); myInputBox->close();
break; break;
@ -322,11 +330,13 @@ void RamWidget::showInputBox(int cmd)
// Add inputbox in the middle of the RAM widget // Add inputbox in the middle of the RAM widget
uInt32 x = getAbsX() + ((getWidth() - myInputBox->getWidth()) >> 1); uInt32 x = getAbsX() + ((getWidth() - myInputBox->getWidth()) >> 1);
uInt32 y = getAbsY() + ((getHeight() - myInputBox->getHeight()) >> 1); uInt32 y = getAbsY() + ((getHeight() - myInputBox->getHeight()) >> 1);
myInputBox->show(x, y); myInputBox->show(x, y);
myInputBox->setText(""); myInputBox->setText("");
myInputBox->setTitle(""); myInputBox->setMessage("");
myInputBox->setFocus(0); myInputBox->setFocus(0);
myInputBox->setEmitSignal(cmd); myInputBox->setEmitSignal(cmd);
myInputBox->setTitle(cmd == kSValEntered ? "Search" : "Compare");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -115,9 +115,9 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
addFocusWidget(myTimWrite); addFocusWidget(myTimWrite);
// Timer registers (RO) // Timer registers (RO)
const char* const readNames[] = { "INTIM", "TIMINT", "Total Clks", "INTIM Clks" }; const char* const readNames[] = { "INTIM", "TIMINT", "Total Clks", "INTIM Clks", "Divider" };
xpos = 10; ypos += myTimWrite->getHeight() + lineHeight; xpos = 10; ypos += myTimWrite->getHeight() + lineHeight / 2;
for(int row = 0; row < 4; ++row) for(int row = 0; row < 5; ++row)
{ {
t = new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 2, t = new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 2,
10*fontWidth, fontHeight, readNames[row], TextAlign::Left); 10*fontWidth, fontHeight, readNames[row], TextAlign::Left);
@ -127,6 +127,11 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
myTimRead->setTarget(this); myTimRead->setTarget(this);
myTimRead->setEditable(false); myTimRead->setEditable(false);
ypos += myTimRead->getHeight() - 1;
myTimDivider = new DataGridWidget(boss, nfont, xpos, ypos, 1, 1, 4, 32, Common::Base::F_10_4);
myTimDivider->setTarget(this);
myTimDivider->setEditable(false);
// Controller ports // Controller ports
const RiotDebug& riot = instance().debugger().riotDebug(); const RiotDebug& riot = instance().debugger().riotDebug();
xpos = col; ypos = 10; xpos = col; ypos = 10;
@ -315,6 +320,11 @@ void RiotWidget::loadConfig()
changed.push_back(state.INTIMCLKS != oldstate.INTIMCLKS); changed.push_back(state.INTIMCLKS != oldstate.INTIMCLKS);
myTimRead->setList(alist, vlist, changed); myTimRead->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
alist.push_back(0); vlist.push_back(state.TIMDIV);
changed.push_back(state.TIMDIV != oldstate.TIMDIV);
myTimDivider->setList(alist, vlist, changed);
// Console switches (inverted, since 'selected' in the UI // Console switches (inverted, since 'selected' in the UI
// means 'grounded' in the system) // means 'grounded' in the system)
myP0Diff->setSelectedIndex(riot.diffP0(), state.swchbReadBits[1] != oldstate.swchbReadBits[1]); myP0Diff->setSelectedIndex(riot.diffP0(), state.swchbReadBits[1] != oldstate.swchbReadBits[1]);

View File

@ -59,6 +59,7 @@ class RiotWidget : public Widget, public CommandSender
DataGridWidget* myTimWrite; DataGridWidget* myTimWrite;
DataGridWidget* myTimRead; DataGridWidget* myTimRead;
DataGridWidget* myTimDivider;
ControllerWidget *myLeftControl, *myRightControl; ControllerWidget *myLeftControl, *myRightControl;
PopUpWidget *myP0Diff, *myP1Diff; PopUpWidget *myP0Diff, *myP1Diff;

View File

@ -288,6 +288,20 @@ void RomListWidget::handleMouseWheel(int x, int y, int direction)
myScrollBar->handleMouseWheel(x, y, direction); myScrollBar->handleMouseWheel(x, y, direction);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomListWidget::handleMouseEntered()
{
setFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomListWidget::handleMouseLeft()
{
clearFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RomListWidget::handleText(char text) bool RomListWidget::handleText(char text)
{ {
@ -458,9 +472,7 @@ void RomListWidget::drawWidget(bool hilite)
const GUI::Rect& l = getLineRect(); const GUI::Rect& l = getLineRect();
// Draw a thin frame around the list and to separate columns // Draw a thin frame around the list and to separate columns
s.hLine(_x, _y, _x + _w - 1, kColor); s.frameRect(_x, _y, _w + 1, _h, hilite ? kWidColorHi : kColor);
s.hLine(_x, _y + _h - 1, _x + _w - 1, kShadowColor);
s.vLine(_x, _y, _y + _h - 1, kColor);
s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor); s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor);
// Draw the list items // Draw the list items
@ -484,7 +496,7 @@ void RomListWidget::drawWidget(bool hilite)
// Draw highlighted item in a frame // Draw highlighted item in a frame
if (_highlightedItem == pos) if (_highlightedItem == pos)
s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _fontHeight, kTextColorHi); s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _fontHeight, kWidColorHi);
// Draw the selected item inverted, on a highlighted background. // Draw the selected item inverted, on a highlighted background.
if(_selectedItem == pos && _hasFocus) if(_selectedItem == pos && _hasFocus)
@ -495,7 +507,7 @@ void RomListWidget::drawWidget(bool hilite)
bytesColor = kTextColorInv; bytesColor = kTextColorInv;
} }
else else
s.frameRect(_x + r.x() - 3, ypos - 1, r.width(), _fontHeight, kTextColorHi); s.frameRect(_x + r.x() - 3, ypos - 1, r.width(), _fontHeight, kWidColorHi);
} }
// Draw labels // Draw labels

View File

@ -61,6 +61,8 @@ class RomListWidget : public EditableWidget
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;
void handleMouseEntered() override;
void handleMouseLeft() override;
bool handleText(char text) override; bool handleText(char text) override;
bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyDown(StellaKey key, StellaMod mod) override;
bool handleKeyUp(StellaKey key, StellaMod mod) override; bool handleKeyUp(StellaKey key, StellaMod mod) override;

View File

@ -164,9 +164,18 @@ void TiaZoomWidget::handleMouseMoved(int x, int y)
#endif #endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaZoomWidget::handleMouseEntered()
{
setFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaZoomWidget::handleMouseLeft() void TiaZoomWidget::handleMouseLeft()
{ {
clearFlags(WIDGET_HILITED);
setDirty();
myMouseMoving = false; myMouseMoving = false;
} }
@ -242,11 +251,7 @@ void TiaZoomWidget::drawWidget(bool hilite)
FBSurface& s = dialog().surface(); FBSurface& s = dialog().surface();
s.fillRect(_x+1, _y+1, _w-2, _h-2, kBGColor); s.fillRect(_x+1, _y+1, _w-2, _h-2, kBGColor);
#ifndef FLAT_UI s.frameRect(_x, _y, _w, _h, hilite ? kWidColorHi : kColor);
s.box(_x, _y, _w, _h, kColor, kShadowColor);
#else
s.frameRect(_x, _y, _w, _h, kColor);
#endif
// Draw the zoomed image // Draw the zoomed image
// This probably isn't as efficient as it can be, but it's a small area // This probably isn't as efficient as it can be, but it's a small area
@ -269,11 +274,7 @@ void TiaZoomWidget::drawWidget(bool hilite)
{ {
uInt32 idx = y*width + x; uInt32 idx = y*width + x;
uInt32 color = currentFrame[idx] | (idx > scanoffset ? 1 : 0); uInt32 color = currentFrame[idx] | (idx > scanoffset ? 1 : 0);
#ifndef FLAT_UI
s.fillRect(_x + col + 2, _y + row + 2, wzoom, hzoom, color);
#else
s.fillRect(_x + col + 1, _y + row + 1, wzoom, hzoom, color); s.fillRect(_x + col + 1, _y + row + 1, wzoom, hzoom, color);
#endif
} }
} }
} }

View File

@ -35,6 +35,9 @@ class TiaZoomWidget : public Widget, public CommandSender
void loadConfig() override; void loadConfig() override;
void setPos(int x, int y); void setPos(int x, int y);
protected:
void handleMouseEntered() override;
private: private:
void zoom(int level); void zoom(int level);
void recalc(); void recalc();

View File

@ -76,23 +76,16 @@ void ToggleBitWidget::drawWidget(bool hilite)
int row, col; int row, col;
string buffer; string buffer;
s.frameRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor);
// Draw the internal grid and labels // Draw the internal grid and labels
int linewidth = _cols * _colWidth; int linewidth = _cols * _colWidth;
#ifndef FLAT_UI
for (row = 0; row <= _rows; row++)
s.hLine(_x, _y + (row * _rowHeight), _x + linewidth, kColor);
int lineheight = _rows * _rowHeight;
for (col = 0; col <= _cols; col++)
s.vLine(_x + (col * _colWidth), _y, _y + lineheight, kColor);
#else
s.frameRect(_x, _y, _w, _h, kColor);
for(row = 1; row <= _rows - 1; row++) for(row = 1; row <= _rows - 1; row++)
s.hLine(_x + 1, _y + (row * _rowHeight), _x + linewidth - 1, kBGColorLo); s.hLine(_x + 1, _y + (row * _rowHeight), _x + linewidth - 1, kBGColorLo);
int lineheight = _rows * _rowHeight; int lineheight = _rows * _rowHeight;
for(col = 1; col <= _cols - 1; col++) for(col = 1; col <= _cols - 1; col++)
s.vLine(_x + (col * _colWidth), _y + 1, _y + lineheight - 1, kBGColorLo); s.vLine(_x + (col * _colWidth), _y + 1, _y + lineheight - 1, kBGColorLo);
#endif
// Draw the list items // Draw the list items
for (row = 0; row < _rows; row++) for (row = 0; row < _rows; row++)

View File

@ -123,12 +123,14 @@ void TogglePixelWidget::drawWidget(bool hilite)
FBSurface& s = dialog().surface(); FBSurface& s = dialog().surface();
int row, col; int row, col;
s.frameRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor);
// Draw the internal grid and labels // Draw the internal grid and labels
int linewidth = _cols * _colWidth; int linewidth = _cols * _colWidth;
for (row = 0; row <= _rows; row++) for (row = 1; row <= _rows - 1; row++)
s.hLine(_x, _y + (row * _rowHeight), _x + linewidth, kColor); s.hLine(_x, _y + (row * _rowHeight), _x + linewidth, kColor);
int lineheight = _rows * _rowHeight; int lineheight = _rows * _rowHeight;
for (col = 0; col <= _cols; col++) for (col = 1; col <= _cols - 1; col++)
s.vLine(_x + (col * _colWidth), _y, _y + lineheight, kColor); s.vLine(_x + (col * _colWidth), _y, _y + lineheight, kColor);
// Draw the pixels // Draw the pixels
@ -155,10 +157,6 @@ void TogglePixelWidget::drawWidget(bool hilite)
// Cross out the bits? // Cross out the bits?
if(_crossBits) if(_crossBits)
{ {
#ifndef FLAT_UI
for(row = 1; row < 4; ++row)
s.hLine(_x, _y + (row * lineheight / 4), _x + linewidth, kColor);
#else
for(col = 0; col < _cols; ++col) for(col = 0; col < _cols; ++col)
{ {
int x = _x + col * _colWidth; int x = _x + col * _colWidth;
@ -166,6 +164,5 @@ void TogglePixelWidget::drawWidget(bool hilite)
s.line(x + 1, _y + 1, x + _colWidth - 1, _y + lineheight - 1, kColor); s.line(x + 1, _y + 1, x + _colWidth - 1, _y + lineheight - 1, kColor);
s.line(x + _colWidth - 1, _y + 1, x + 1, _y + lineheight - 1, kColor); s.line(x + _colWidth - 1, _y + 1, x + 1, _y + lineheight - 1, kColor);
} }
#endif
} }
} }

View File

@ -40,6 +40,20 @@ ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font,
WIDGET_WANTS_RAWDATA; WIDGET_WANTS_RAWDATA;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ToggleWidget::handleMouseEntered()
{
setFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ToggleWidget::handleMouseLeft()
{
clearFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
{ {

View File

@ -68,6 +68,8 @@ class ToggleWidget : public Widget, public CommandSender
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 handleMouseEntered() override;
void handleMouseLeft() override;
bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyDown(StellaKey key, StellaMod mod) override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override;

View File

@ -294,33 +294,25 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
{ {
myOSystem.frameBuffer().toggleFullscreen(); myOSystem.frameBuffer().toggleFullscreen();
} }
// state rewinding must work in pause mode too // State rewinding must work in pause mode too
else if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE) else if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE)
{ {
switch(key) switch(key)
{ {
case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states
myOSystem.frameBuffer().setPauseDelay(); enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, false);
setEventState(EventHandlerState::PAUSE);
myOSystem.state().rewindState((StellaModTest::isShift(mod) && state) ? 10 : 1);
break; break;
case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states
myOSystem.frameBuffer().setPauseDelay(); enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, true);
setEventState(EventHandlerState::PAUSE);
myOSystem.state().unwindState((StellaModTest::isShift(mod) && state) ? 10 : 1);
break; break;
case KBDK_DOWN: // Alt-down rewinds to start of list case KBDK_DOWN: // Alt-down rewinds to start of list
myOSystem.frameBuffer().setPauseDelay(); enterTimeMachineMenuMode(1000, false);
setEventState(EventHandlerState::PAUSE);
myOSystem.state().rewindState(1000);
break; break;
case KBDK_UP: // Alt-up rewinds to end of list case KBDK_UP: // Alt-up rewinds to end of list
myOSystem.frameBuffer().setPauseDelay(); enterTimeMachineMenuMode(1000, true);
setEventState(EventHandlerState::PAUSE);
myOSystem.state().unwindState(1000);
break; break;
default: default:
@ -329,7 +321,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
} }
} }
// These only work when in emulation mode // These only work when in emulation mode
if(!handled && myState == EventHandlerState::EMULATION) if(!handled && (myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE))
{ {
handled = true; handled = true;
switch(key) switch(key)
@ -539,7 +531,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
handleEvent(Event::Quit, 1); handleEvent(Event::Quit, 1);
} }
// These only work when in emulation mode // These only work when in emulation mode
else if(myState == EventHandlerState::EMULATION) else if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE)
{ {
switch(key) switch(key)
{ {
@ -614,11 +606,34 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
// Don't pass the key on if we've already taken care of it // Don't pass the key on if we've already taken care of it
if(handled) return; if(handled) return;
// Handle keys which switch eventhandler state
// Arrange the logic to take advantage of short-circuit evaluation // Arrange the logic to take advantage of short-circuit evaluation
if(!(StellaModTest::isControl(mod) || StellaModTest::isShift(mod) || StellaModTest::isAlt(mod)) && if(!(StellaModTest::isControl(mod) || StellaModTest::isShift(mod) || StellaModTest::isAlt(mod)))
!state && eventStateChange(myKeyTable[key][kEmulationMode])) {
// special handling for Escape key
if(state && key == KBDK_ESCAPE)
{
if(myState == EventHandlerState::PAUSE)
{
setEventState(EventHandlerState::EMULATION);
return; return;
}
else if(myState == EventHandlerState::CMDMENU ||
myState == EventHandlerState::TIMEMACHINE)
{
leaveMenuMode();
return;
}
else if(myState == EventHandlerState::DEBUGGER && myOSystem.debugger().canExit())
{
leaveDebugMode();
return;
}
}
// Handle keys which switch eventhandler state
if(!state && eventStateChange(myKeyTable[key][kEmulationMode]))
return;
}
// Otherwise, let the event handler deal with it // Otherwise, let the event handler deal with it
switch(myState) switch(myState)
@ -919,7 +934,7 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::handleEvent(Event::Type event, int state) void EventHandler::handleEvent(Event::Type event, Int32 state)
{ {
// Take care of special events that aren't part of the emulation core // Take care of special events that aren't part of the emulation core
// or need to be preprocessed before passing them on // or need to be preprocessed before passing them on
@ -1223,14 +1238,14 @@ bool EventHandler::eventStateChange(Event::Type type)
break; break;
case Event::OptionsMenuMode: case Event::OptionsMenuMode:
if(myState == EventHandlerState::EMULATION) if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE)
enterMenuMode(EventHandlerState::OPTIONSMENU); enterMenuMode(EventHandlerState::OPTIONSMENU);
else else
handled = false; handled = false;
break; break;
case Event::CmdMenuMode: case Event::CmdMenuMode:
if(myState == EventHandlerState::EMULATION) if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE)
enterMenuMode(EventHandlerState::CMDMENU); enterMenuMode(EventHandlerState::CMDMENU);
else if(myState == EventHandlerState::CMDMENU) else if(myState == EventHandlerState::CMDMENU)
leaveMenuMode(); leaveMenuMode();
@ -1239,8 +1254,8 @@ bool EventHandler::eventStateChange(Event::Type type)
break; break;
case Event::TimeMachineMode: case Event::TimeMachineMode:
if(myState == EventHandlerState::EMULATION) if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE)
enterMenuMode(EventHandlerState::TIMEMACHINE); enterTimeMachineMenuMode(0, false);
else if(myState == EventHandlerState::TIMEMACHINE) else if(myState == EventHandlerState::TIMEMACHINE)
leaveMenuMode(); leaveMenuMode();
else else
@ -1248,9 +1263,10 @@ bool EventHandler::eventStateChange(Event::Type type)
break; break;
case Event::DebuggerMode: case Event::DebuggerMode:
if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE) if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE
|| myState == EventHandlerState::TIMEMACHINE)
enterDebugMode(); enterDebugMode();
else if(myState == EventHandlerState::DEBUGGER) else if(myState == EventHandlerState::DEBUGGER && myOSystem.debugger().canExit())
leaveDebugMode(); leaveDebugMode();
else else
handled = false; handled = false;
@ -2139,6 +2155,17 @@ void EventHandler::leaveDebugMode()
#endif #endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
// TODO: display last wind message (numWinds != 0) in time machine dialog
enterMenuMode(EventHandlerState::TIMEMACHINE);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setEventState(EventHandlerState state) void EventHandler::setEventState(EventHandlerState state)
{ {

View File

@ -24,7 +24,6 @@ class Console;
class OSystem; class OSystem;
class MouseControl; class MouseControl;
class DialogContainer; class DialogContainer;
class EventMappingWidget;
#include "Event.hxx" #include "Event.hxx"
#include "EventHandlerConstants.hxx" #include "EventHandlerConstants.hxx"
@ -137,6 +136,7 @@ class EventHandler
void leaveMenuMode(); void leaveMenuMode();
bool enterDebugMode(); bool enterDebugMode();
void leaveDebugMode(); void leaveDebugMode();
void enterTimeMachineMenuMode(uInt32 numWinds, bool unwind);
void takeSnapshot(uInt32 number = 0); void takeSnapshot(uInt32 number = 0);
/** /**
@ -473,7 +473,6 @@ class EventHandler
The following methods take care of assigning action mappings. The following methods take care of assigning action mappings.
*/ */
void setActionMappings(EventMode mode); void setActionMappings(EventMode mode);
void setKeyNames();
void setKeymap(); void setKeymap();
void setDefaultKeymap(Event::Type, EventMode mode); void setDefaultKeymap(Event::Type, EventMode mode);
void setDefaultJoymap(Event::Type, EventMode mode); void setDefaultJoymap(Event::Type, EventMode mode);

View File

@ -154,8 +154,15 @@ void FBSurface::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::drawChar(const GUI::Font& font, uInt8 chr, void FBSurface::drawChar(const GUI::Font& font, uInt8 chr,
uInt32 tx, uInt32 ty, uInt32 color) uInt32 tx, uInt32 ty, uInt32 color, uInt32 shadowColor)
{ {
if(shadowColor != 0)
{
drawChar(font, chr, tx + 1, ty + 0, shadowColor);
drawChar(font, chr, tx + 0, ty + 1, shadowColor);
drawChar(font, chr, tx + 1, ty + 1, shadowColor);
}
const FontDesc& desc = font.desc(); const FontDesc& desc = font.desc();
// If this character is not included in the font, use the default char. // If this character is not included in the font, use the default char.
@ -263,24 +270,6 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
case FrameStyle::Dashed: case FrameStyle::Dashed:
uInt32 i, skip, lwidth = 1; uInt32 i, skip, lwidth = 1;
#ifndef FLAT_UI
for(i = x, skip = 1; i < x+w-1; i=i+lwidth+1, ++skip)
{
if(skip % 2)
{
hLine(i, y, i + lwidth, color);
hLine(i, y + h - 1, i + lwidth, color);
}
}
for(i = y, skip = 1; i < y+h-1; i=i+lwidth+1, ++skip)
{
if(skip % 2)
{
vLine(x, i, i + lwidth, color);
vLine(x + w - 1, i, i + lwidth, color);
}
}
#else
for(i = x; i < x + w; i += 2) for(i = x; i < x + w; i += 2)
{ {
hLine(i, y, i, color); hLine(i, y, i, color);
@ -291,7 +280,6 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
vLine(x, i, i, color); vLine(x, i, i, color);
vLine(x + w - 1, i, i, color); vLine(x + w - 1, i, i, color);
} }
#endif
break; break;
} }
} }
@ -300,7 +288,7 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
void FBSurface::drawString(const GUI::Font& font, const string& s, void FBSurface::drawString(const GUI::Font& font, const string& s,
int x, int y, int w, int x, int y, int w,
uInt32 color, TextAlign align, uInt32 color, TextAlign align,
int deltax, bool useEllipsis) int deltax, bool useEllipsis, uInt32 shadowColor)
{ {
const string ELLIPSIS = "\x1d"; // "..." const string ELLIPSIS = "\x1d"; // "..."
const int leftX = x, rightX = x + w; const int leftX = x, rightX = x + w;
@ -313,43 +301,22 @@ void FBSurface::drawString(const GUI::Font& font, const string& s,
// String is too wide. So we shorten it "intelligently", by replacing // String is too wide. So we shorten it "intelligently", by replacing
// parts of it by an ellipsis ("..."). There are three possibilities // parts of it by an ellipsis ("..."). There are three possibilities
// for this: replace the start, the end, or the middle of the string. // for this: replace the start, the end, or the middle of the string.
// What is best really depends on the context; but unless we want to // What is best really depends on the context; but most applications
// make this configurable, replacing the middle probably is a good // replace the end. So we use that too.
// compromise. int w2 = font.getStringWidth(ELLIPSIS);
const int ellipsisWidth = font.getStringWidth(ELLIPSIS);
// SLOW algorithm to remove enough of the middle. But it is good enough for now.
const int halfWidth = (w - ellipsisWidth) / 2;
int w2 = 0;
// SLOW algorithm to find the acceptable length. But it is good enough for now.
for(i = 0; i < s.size(); ++i) for(i = 0; i < s.size(); ++i)
{ {
int charWidth = font.getCharWidth(s[i]); int charWidth = font.getCharWidth(s[i]);
if(w2 + charWidth > halfWidth) if(w2 + charWidth > w)
break; break;
w2 += charWidth; w2 += charWidth;
str += s[i]; str += s[i];
} }
// At this point we know that the first 'i' chars are together 'w2'
// pixels wide. We took the first i-1, and add "..." to them.
str += ELLIPSIS; str += ELLIPSIS;
// The original string is width wide. Of those we already skipped past
// w2 pixels, which means (width - w2) remain.
// The new str is (w2+ellipsisWidth) wide, so we can accomodate about
// (w - (w2+ellipsisWidth)) more pixels.
// Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) =
// (width + ellipsisWidth - w)
int skip = width + ellipsisWidth - w;
for(; i < s.size() && skip > 0; ++i)
skip -= font.getCharWidth(s[i]);
// Append the remaining chars, if any
for(; i < s.size(); ++i)
str += s[i];
width = font.getStringWidth(str); width = font.getStringWidth(str);
} }
else else
@ -367,7 +334,7 @@ void FBSurface::drawString(const GUI::Font& font, const string& s,
if(x+w > rightX) if(x+w > rightX)
break; break;
if(x >= leftX) if(x >= leftX)
drawChar(font, str[i], x, y, color); drawChar(font, str[i], x, y, color, shadowColor);
x += w; x += w;
} }

View File

@ -134,7 +134,7 @@ class FBSurface
@param color The color of the character @param color The color of the character
*/ */
virtual void drawChar(const GUI::Font& font, uInt8 c, uInt32 x, uInt32 y, virtual void drawChar(const GUI::Font& font, uInt8 c, uInt32 x, uInt32 y,
uInt32 color); uInt32 color, uInt32 shadowColor = 0);
/** /**
This method should be called to draw the bitmap image. This method should be called to draw the bitmap image.
@ -217,7 +217,7 @@ class FBSurface
virtual void drawString( virtual void drawString(
const GUI::Font& font, const string& s, int x, int y, int w, const GUI::Font& font, const string& s, int x, int y, int w,
uInt32 color, TextAlign align = TextAlign::Left, uInt32 color, TextAlign align = TextAlign::Left,
int deltax = 0, bool useEllipsis = true); int deltax = 0, bool useEllipsis = true, uInt32 shadowColor = 0);
/** /**
This method should be called to indicate that the surface has been This method should be called to indicate that the surface has been

View File

@ -46,10 +46,12 @@ FrameBuffer::FrameBuffer(OSystem& osystem)
: myOSystem(osystem), : myOSystem(osystem),
myInitializedCount(0), myInitializedCount(0),
myPausedCount(0), myPausedCount(0),
myCurrentModeList(nullptr) myStatsEnabled(false),
myLastFrameRate(60),
myCurrentModeList(nullptr),
myTotalTime(0),
myTotalFrames(0)
{ {
myMsg.surface = myStatsMsg.surface = nullptr;
myStatsEnabled = myMsg.enabled = myStatsMsg.enabled = false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -229,8 +231,8 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
// Create surfaces for TIA statistics and general messages // Create surfaces for TIA statistics and general messages
myStatsMsg.color = kColorInfo; myStatsMsg.color = kColorInfo;
myStatsMsg.w = infoFont().getMaxCharWidth() * 24 + 2; myStatsMsg.w = font().getMaxCharWidth() * 30 + 3;
myStatsMsg.h = (infoFont().getFontHeight() + 2) * 2; myStatsMsg.h = (font().getFontHeight() + 2) * 2;
if(!myStatsMsg.surface) if(!myStatsMsg.surface)
{ {
@ -285,36 +287,10 @@ void FrameBuffer::update()
// Show frame statistics // Show frame statistics
if(myStatsMsg.enabled) if(myStatsMsg.enabled)
{ drawFrameStats();
const ConsoleInfo& info = myOSystem.console().about(); else
char msg[30]; myLastFrameRate = myOSystem.console().getFramerate();
std::snprintf(msg, 30, "%3u @ %3.2ffps => %s", myLastScanlines = myOSystem.console().tia().scanlinesLastFrame();
myOSystem.console().tia().scanlinesLastFrame(),
myOSystem.console().getFramerate(), info.DisplayFormat.c_str());
myStatsMsg.surface->invalidate();
string bsinfo = info.BankSwitch +
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player");
// draw shadowed text
myStatsMsg.surface->drawString(infoFont(), msg, 1 + 1, 1 + 0,
myStatsMsg.w, kBGColor);
myStatsMsg.surface->drawString(infoFont(), msg, 1 + 0, 1 + 1,
myStatsMsg.w, kBGColor);
myStatsMsg.surface->drawString(infoFont(), msg, 1 + 1, 1 + 1,
myStatsMsg.w, kBGColor);
myStatsMsg.surface->drawString(infoFont(), msg, 1, 1,
myStatsMsg.w, myStatsMsg.color);
myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 1, 15 + 0,
myStatsMsg.w, kBGColor);
myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 0, 15 + 1,
myStatsMsg.w, kBGColor);
myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 1, 15 + 1,
myStatsMsg.w, kBGColor);
myStatsMsg.surface->drawString(infoFont(), bsinfo, 1, 15,
myStatsMsg.w, myStatsMsg.color);
myStatsMsg.surface->setDirty();
myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1);
myStatsMsg.surface->render();
}
myPausedCount = 0; myPausedCount = 0;
break; // EventHandlerState::EMULATION break; // EventHandlerState::EMULATION
} }
@ -400,6 +376,66 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
myMsg.enabled = true; myMsg.enabled = true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::drawFrameStats()
{
const ConsoleInfo& info = myOSystem.console().about();
char msg[30];
uInt32 color;
const int XPOS = 2, YPOS = 0;
int xPos = XPOS;
myStatsMsg.surface->invalidate();
string bsinfo = info.BankSwitch +
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player");
// draw shadowed text
color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ? 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);
xPos += font().getStringWidth(msg);
std::snprintf(msg, 30, " => %s", info.DisplayFormat.c_str());
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
xPos += font().getStringWidth(msg);
// draw framerate
float frameRate;
/*if(myOSystem.settings().getInt("framerate") == 0)
{
// if 'Auto' is selected, draw the calculated framerate
frameRate = myOSystem.console().getFramerate();
}
else*/
{
// if 'Auto' is not selected, draw the effective framerate
const TimingInfo& ti = myOSystem.timingInfo();
if(ti.totalFrames - myTotalFrames >= myLastFrameRate)
{
frameRate = 1000000.0 * (ti.totalFrames - myTotalFrames) / (ti.totalTime - myTotalTime);
if(frameRate > myOSystem.console().getFramerate() + 1)
frameRate = 1;
myTotalFrames = ti.totalFrames;
myTotalTime = ti.totalTime;
}
else
frameRate = myLastFrameRate;
}
myLastFrameRate = frameRate;
std::snprintf(msg, 30, " @ %5.2ffps", frameRate);
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
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->render();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::toggleFrameStats() void FrameBuffer::toggleFrameStats()
{ {
@ -490,11 +526,7 @@ inline void FrameBuffer::drawMessage()
myMsg.surface->setDstPos(myMsg.x + myImageRect.x(), myMsg.y + myImageRect.y()); myMsg.surface->setDstPos(myMsg.x + myImageRect.x(), myMsg.y + myImageRect.y());
myMsg.surface->fillRect(1, 1, myMsg.w-2, myMsg.h-2, kBtnColor); myMsg.surface->fillRect(1, 1, myMsg.w-2, myMsg.h-2, kBtnColor);
#ifndef FLAT_UI
myMsg.surface->box(0, 0, myMsg.w, myMsg.h, kColor, kShadowColor);
#else
myMsg.surface->frameRect(0, 0, myMsg.w, myMsg.h, kColor); myMsg.surface->frameRect(0, 0, myMsg.w, myMsg.h, kColor);
#endif
myMsg.surface->drawString(font(), myMsg.text, 5, 4, myMsg.surface->drawString(font(), myMsg.text, 5, 4,
myMsg.w, myMsg.color, TextAlign::Left); myMsg.w, myMsg.color, TextAlign::Left);
@ -957,14 +989,17 @@ void FrameBuffer::VideoModeList::setZoom(uInt32 zoom)
kTextColor Normal text color kTextColor Normal text color
kTextColorHi Highlighted text color kTextColorHi Highlighted text color
kTextColorEm Emphasized text color kTextColorEm Emphasized text color
kTextColorSel Color for selected text kTextColorInv Color for selected text
*** UI elements (dialog and widgets) *** *** UI elements (dialog and widgets) ***
kDlgColor Dialog background kDlgColor Dialog background
kWidColor Widget background kWidColor Widget background
kWidColorHi Widget highlight color
kWidFrameColor Border for currently selected widget kWidFrameColor Border for currently selected widget
*** Button colors *** *** Button colors ***
kBtnColor Normal button background kBtnColor Normal button background
kBtnColorHi Highlighted button background kBtnColorHi Highlighted button background
kBtnBorderColor,
kBtnBorderColorHi,
kBtnTextColor Normal button font color kBtnTextColor Normal button font color
kBtnTextColorHi Highlighted button font color kBtnTextColorHi Highlighted button font color
*** Checkbox colors *** *** Checkbox colors ***
@ -975,47 +1010,53 @@ void FrameBuffer::VideoModeList::setZoom(uInt32 zoom)
*** Slider colors *** *** Slider colors ***
kSliderColor, kSliderColor,
kSliderColorHi kSliderColorHi
kSliderBGColor
kSliderBGColorHi
kSliderBGColorLo,
*** Debugger colors *** *** Debugger colors ***
kDbgChangedColor Background color for changed cells kDbgChangedColor Background color for changed cells
kDbgChangedTextColor Text color for changed cells kDbgChangedTextColor Text color for changed cells
kDbgColorHi Highlighted color in debugger data cells kDbgColorHi Highlighted color in debugger data cells
kDbgColorRed Red color in debugger kDbgColorRed Red color in debugger
*** Info color *** *** Other colors ***
kColorinfo kColorInfo TIA output position color
kColorTitleBar Title bar color
kColorTitleText Title text color
kColorTitleBarLo Disabled title bar color
kColorTitleTextLo Disabled title text color
*/ */
uInt32 FrameBuffer::ourGUIColors[3][kNumColors-256] = { uInt32 FrameBuffer::ourGUIColors[3][kNumColors-256] = {
// Standard // Standard
{ 0x686868, 0x000000, 0xa38c61, 0xdccfa5, 0x404040, { 0x686868, 0x000000, 0xa38c61, 0xdccfa5, 0x404040, // base
0x000000, 0x62a108, 0x9f0000, 0x000000, 0x000000, 0xac3410, 0x9f0000, 0xf0f0cf, // text
0xc9af7c, 0xf0f0cf, 0xc80000, 0xc9af7c, 0xf0f0cf, 0xd55941, 0xc80000, // UI elements
0xac3410, 0xd55941, 0xffffff, 0xffd652, 0xac3410, 0xd55941, 0x686868, 0xdccfa5, 0xf0f0cf, 0xf0f0cf, // buttons
0xac3410, 0xac3410, // checkbox
0xac3410, 0xd55941, 0xac3410, 0xd55941, // scrollbar
0xac3410, 0xd55941, 0xac3410, 0xd55941, 0xdccfa5, 0xf0f0cf, 0xa38c61, // slider
0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000, 0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000, // debugger
0xffffff 0xffffff, 0xac3410, 0xf0f0cf, 0x686868, 0xdccfa5 // other
}, },
// Classic // Classic
{ 0x686868, 0x000000, 0x404040, 0x404040, 0x404040, { 0x686868, 0x000000, 0x404040, 0x404040, 0x404040, // base
0x20a020, 0x00ff00, 0xc80000, 0x20a020, 0x20a020, 0x00ff00, 0xc80000, 0x000000, // text
0x000000, 0x000000, 0xc80000, 0x000000, 0x000000, 0x00ff00, 0xc80000, // UI elements
0x000000, 0x000000, 0x20a020, 0x00ff00, 0x000000, 0x000000, 0x686868, 0x00ff00, 0x20a020, 0x00ff00, // buttons
0x20a020, 0x20a020, // checkbox
0x20a020, 0x00ff00, 0x20a020, 0x00ff00, // scrollbar
0x20a020, 0x00ff00, 0x20a020, 0x00ff00, 0x404040, 0x686868, 0x404040, // slider
0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000, 0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000, // debugger
0x20a020 0x20a020, 0x20a020, 0x000000, 0x686868, 0x404040 // other
}, },
// Light // Light
{ { 0x808080, 0x000000, 0xc0c0c0, 0xe1e1e1, 0x333333, // base
0x808080, 0x000000, 0xc0c0c0, 0xe1e1e1, 0x333333, // base 0x000000, 0xBDDEF9, 0x0078d7, 0x000000, // text
0x000000, 0x0078d7, 0x0078d7, 0xffffff, // text 0xf0f0f0, 0xffffff, 0x0078d7, 0x0f0f0f, // UI elements
0xf0f0f0, 0xffffff, 0x0f0f0f, // elements 0xe1e1e1, 0xe5f1fb, 0x808080, 0x0078d7, 0x000000, 0x000000, // buttons
0xe1e1e1, 0xe5f1fb, 0x000000, 0x000000, // buttons
0x333333, // checkbox 0x333333, // checkbox
0x808080, 0x0078d7, // scrollbar 0xc0c0c0, 0x808080, // scrollbar
0x333333, 0x0078d7, // slider 0x333333, 0x0078d7, 0xc0c0c0, 0x808080, 0xe1e1e1, // slider
0xffc0c0, 0x000000, 0xe00000, 0xc00000, // debugger 0xffc0c0, 0x000000, 0xe00000, 0xc00000, // debugger
0xffffff // info 0xffffff, 0x333333, 0xf0f0f0, 0x808080, 0xc0c0c0 // other
} }
}; };

View File

@ -458,6 +458,9 @@ class FrameBuffer
string myScreenTitle; string myScreenTitle;
private: private:
// Draws the frame stats overlay
void drawFrameStats();
// Indicates the number of times the framebuffer was initialized // Indicates the number of times the framebuffer was initialized
uInt32 myInitializedCount; uInt32 myInitializedCount;
@ -506,10 +509,14 @@ class FrameBuffer
uInt32 color; uInt32 color;
shared_ptr<FBSurface> surface; shared_ptr<FBSurface> surface;
bool enabled; bool enabled;
Message() : counter(0), x(0), y(0), w(0), h(0), color(0), enabled(false) { }
}; };
Message myMsg; Message myMsg;
Message myStatsMsg; Message myStatsMsg;
bool myStatsEnabled; bool myStatsEnabled;
uInt32 myLastScanlines;
float myLastFrameRate;
bool myGrabMouse; bool myGrabMouse;
@ -530,6 +537,9 @@ class FrameBuffer
// Holds UI palette data (standard and classic colours) // Holds UI palette data (standard and classic colours)
static uInt32 ourGUIColors[3][kNumColors-256]; static uInt32 ourGUIColors[3][kNumColors-256];
uInt64 myTotalTime;
uInt64 myTotalFrames;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
FrameBuffer() = delete; FrameBuffer() = delete;

View File

@ -53,9 +53,12 @@ enum {
kTextColorInv, kTextColorInv,
kDlgColor, kDlgColor,
kWidColor, kWidColor,
kWidColorHi,
kWidFrameColor, kWidFrameColor,
kBtnColor, kBtnColor,
kBtnColorHi, kBtnColorHi,
kBtnBorderColor,
kBtnBorderColorHi,
kBtnTextColor, kBtnTextColor,
kBtnTextColorHi, kBtnTextColorHi,
kCheckColor, kCheckColor,
@ -63,11 +66,18 @@ enum {
kScrollColorHi, kScrollColorHi,
kSliderColor, kSliderColor,
kSliderColorHi, kSliderColorHi,
kSliderBGColor,
kSliderBGColorHi,
kSliderBGColorLo,
kDbgChangedColor, kDbgChangedColor,
kDbgChangedTextColor, kDbgChangedTextColor,
kDbgColorHi, kDbgColorHi,
kDbgColorRed, kDbgColorRed,
kColorInfo, kColorInfo,
kColorTitleBar,
kColorTitleText,
kColorTitleBarLo,
kColorTitleTextLo,
kNumColors kNumColors
}; };

View File

@ -18,6 +18,9 @@
#include <cstdio> #include <cstdio>
#include "System.hxx" #include "System.hxx"
#include "Settings.hxx"
#include "MT24LC256.hxx" #include "MT24LC256.hxx"
#define DEBUG_EEPROM 0 #define DEBUG_EEPROM 0
@ -250,6 +253,9 @@ void MT24LC256::jpee_data_stop()
{ {
myDataChanged = true; myDataChanged = true;
myPageHit[jpee_address / PAGE_SIZE] = true; myPageHit[jpee_address / PAGE_SIZE] = true;
bool devSettings = mySystem.oSystem().settings().getBool("dev.settings");
if(mySystem.oSystem().settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
mySystem.oSystem().frameBuffer().showMessage("AtariVox/SaveKey EEPROM write");
myData[(jpee_address++) & jpee_sizemask] = jpee_packet[i]; myData[(jpee_address++) & jpee_sizemask] = jpee_packet[i];
if (!(jpee_address & jpee_pagemask)) if (!(jpee_address & jpee_pagemask))
break; /* Writes can't cross page boundary! */ break; /* Writes can't cross page boundary! */
@ -347,6 +353,12 @@ void MT24LC256::jpee_clock_fall()
} }
jpee_state=3; jpee_state=3;
myPageHit[jpee_address / PAGE_SIZE] = true; myPageHit[jpee_address / PAGE_SIZE] = true;
{
bool devSettings = mySystem.oSystem().settings().getBool("dev.settings");
if(mySystem.oSystem().settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
mySystem.oSystem().frameBuffer().showMessage("AtariVox/SaveKey EEPROM read");
}
jpee_nb = (myData[jpee_address & jpee_sizemask] << 1) | 1; /* Fall through */ jpee_nb = (myData[jpee_address & jpee_sizemask] << 1) | 1; /* Fall through */
JPEE_LOG2("I2C_READ(%04X=%02X)",jpee_address,jpee_nb/2); JPEE_LOG2("I2C_READ(%04X=%02X)",jpee_address,jpee_nb/2);
[[fallthrough]]; [[fallthrough]];

View File

@ -633,7 +633,7 @@ void OSystem::mainLoop()
// for that and reset the timers when appropriate // for that and reset the timers when appropriate
if((myTimingInfo.virt - myTimingInfo.current) > (myTimePerFrame << 1)) if((myTimingInfo.virt - myTimingInfo.current) > (myTimePerFrame << 1))
{ {
myTimingInfo.start = myTimingInfo.current = myTimingInfo.virt = getTicks(); myTimingInfo.current = myTimingInfo.virt = getTicks();
} }
if(myTimingInfo.current < myTimingInfo.virt) if(myTimingInfo.current < myTimingInfo.virt)

View File

@ -164,6 +164,7 @@ Settings::Settings(OSystem& osystem)
setInternal("plr.tm.horizon", "10m"); // = ~10 minutes setInternal("plr.tm.horizon", "10m"); // = ~10 minutes
// Thumb ARM emulation options // Thumb ARM emulation options
setInternal("plr.thumb.trapfatal", "false"); setInternal("plr.thumb.trapfatal", "false");
setInternal("plr.eepromaccess", "false");
// developer settings // developer settings
setInternal("dev.settings", "false"); setInternal("dev.settings", "false");
@ -184,6 +185,7 @@ Settings::Settings(OSystem& osystem)
setInternal("dev.tm.horizon", "10s"); // = ~10 seconds setInternal("dev.tm.horizon", "10s"); // = ~10 seconds
// Thumb ARM emulation options // Thumb ARM emulation options
setInternal("dev.thumb.trapfatal", "true"); setInternal("dev.thumb.trapfatal", "true");
setInternal("dev.eepromaccess", "true");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -574,6 +576,7 @@ void Settings::usage() const
<< " -plr.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n" << " -plr.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n"
<< " -plr.tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n" << " -plr.tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n"
<< " -plr.thumb.trapfatal <1|0> Determines whether errors in ARM emulation throw an exception\n" << " -plr.thumb.trapfatal <1|0> Determines whether errors in ARM emulation throw an exception\n"
<< " -plr.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access messages\n"
<< endl << endl
<< " The same parameters but for developer settings mode\n" << " The same parameters but for developer settings mode\n"
<< " -dev.stats <1|0> Overlay console info during emulation\n" << " -dev.stats <1|0> Overlay console info during emulation\n"
@ -587,6 +590,7 @@ void Settings::usage() const
<< " -dev.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n" << " -dev.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n"
<< " -dev.tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n" << " -dev.tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n"
<< " -dev.thumb.trapfatal <1|0> Determines whether errors in ARM emulation throw an exception\n" << " -dev.thumb.trapfatal <1|0> Determines whether errors in ARM emulation throw an exception\n"
<< " -dev.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access messages\n"
<< endl << std::flush; << endl << std::flush;
} }

View File

@ -88,6 +88,13 @@ class System : public Serializable
void reset(bool autodetect = false); void reset(bool autodetect = false);
public: public:
/**
Answer the OSystem attached to the system.
@return The attached OSystem
*/
const OSystem& oSystem() const { return myOSystem; }
/** /**
Answer the 6502 microprocessor attached to the system. If a Answer the 6502 microprocessor attached to the system. If a
processor has not been attached calling this function will fail. processor has not been attached calling this function will fail.

View File

@ -815,10 +815,9 @@ void TIA::update()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIA::enableColorLoss(bool enabled) bool TIA::enableColorLoss(bool enabled)
{ {
if (consoleTiming() != ConsoleTiming::pal) bool allowColorLoss = consoleTiming() == ConsoleTiming::pal;
return false;
if(enabled) if(allowColorLoss && enabled)
{ {
myColorLossEnabled = true; myColorLossEnabled = true;
myColorLossActive = myFrameManager->scanlinesLastFrame() & 0x1; myColorLossActive = myFrameManager->scanlinesLastFrame() & 0x1;
@ -836,7 +835,7 @@ bool TIA::enableColorLoss(bool enabled)
myBackground.applyColorLoss(); myBackground.applyColorLoss();
} }
return true; return allowColorLoss;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -25,7 +25,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent, AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font) const GUI::Font& font)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "About Stella"),
myPage(1), myPage(1),
myNumPages(4), myNumPages(4),
myLinesPerPage(13) myLinesPerPage(13)
@ -40,7 +40,7 @@ AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent,
// Set real dimensions // Set real dimensions
_w = 55 * fontWidth + 8; _w = 55 * fontWidth + 8;
_h = 15 * lineHeight + 20; _h = 15 * lineHeight + 20 + _th;
// Add Previous, Next and Close buttons // Add Previous, Next and Close buttons
xpos = 10; ypos = _h - buttonHeight - 10; xpos = 10; ypos = _h - buttonHeight - 10;
@ -50,7 +50,7 @@ AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent,
myPrevButton->clearFlags(WIDGET_ENABLED); myPrevButton->clearFlags(WIDGET_ENABLED);
wid.push_back(myPrevButton); wid.push_back(myPrevButton);
xpos += buttonWidth + 7; xpos += buttonWidth + 8;
myNextButton = myNextButton =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Next", GuiObject::kNextCmd); "Next", GuiObject::kNextCmd);
@ -61,17 +61,17 @@ AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent,
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Close", GuiObject::kCloseCmd); "Close", GuiObject::kCloseCmd);
wid.push_back(b); wid.push_back(b);
addOKWidget(b); addCancelWidget(b); addCancelWidget(b);
xpos = 5; ypos = 5; xpos = 5; ypos = 5 + _th;
myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - 10, fontHeight, myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - xpos * 2, fontHeight,
"", TextAlign::Center); "", TextAlign::Center);
myTitle->setTextColor(kTextColorEm); myTitle->setTextColor(kTextColorEm);
xpos = 10; ypos += lineHeight + 4; xpos = 16; ypos += lineHeight + 4;
for(int i = 0; i < myLinesPerPage; i++) for(int i = 0; i < myLinesPerPage; i++)
{ {
myDesc.push_back(new StaticTextWidget(this, font, xpos, ypos, _w - 20, myDesc.push_back(new StaticTextWidget(this, font, xpos, ypos, _w - xpos * 2,
fontHeight, "", TextAlign::Left)); fontHeight, "", TextAlign::Left));
myDescStr.push_back(""); myDescStr.push_back("");
ypos += fontHeight; ypos += fontHeight;
@ -116,30 +116,30 @@ void AboutDialog::updateStrings(int page, int lines, string& title)
case 2: case 2:
title = "The Stella Team"; title = "The Stella Team";
ADD_ATEXT("\\L\\c0"" Stephen Anthony"); ADD_ATEXT("\\L\\c0""Stephen Anthony");
ADD_ATEXT("\\L\\c2"" Lead developer, current maintainer for the"); ADD_ATEXT("\\L\\c2"" Lead developer, current maintainer for the");
ADD_ATEXT("\\L\\c2"" Linux/OSX and Windows ports "); ADD_ATEXT("\\L\\c2"" Linux/OSX and Windows ports ");
ADD_ATEXT("\\L\\c0"" Christian Speckner"); ADD_ATEXT("\\L\\c0""Christian Speckner");
ADD_ATEXT("\\L\\c2"" Emulation core development, TIA core"); ADD_ATEXT("\\L\\c2"" Emulation core development, TIA core");
ADD_ATEXT("\\L\\c0"" Eckhard Stolberg"); ADD_ATEXT("\\L\\c0""Eckhard Stolberg");
ADD_ATEXT("\\L\\c2"" Emulation core development"); ADD_ATEXT("\\L\\c2"" Emulation core development");
ADD_ATEXT("\\L\\c0"" Thomas Jentzsch"); ADD_ATEXT("\\L\\c0""Thomas Jentzsch");
ADD_ATEXT("\\L\\c2"" Emulation core development, jack-of-all-trades"); ADD_ATEXT("\\L\\c2"" Emulation core development, jack-of-all-trades");
ADD_ATEXT("\\L\\c0"" Brian Watson"); ADD_ATEXT("\\L\\c0""Brian Watson");
ADD_ATEXT("\\L\\c2"" Emulation core enhancement, debugger support"); ADD_ATEXT("\\L\\c2"" Emulation core enhancement, debugger support");
ADD_ATEXT("\\L\\c0"" Bradford W. Mott"); ADD_ATEXT("\\L\\c0""Bradford W. Mott");
ADD_ATEXT("\\L\\c2"" Original author of Stella"); ADD_ATEXT("\\L\\c2"" Original author of Stella");
break; break;
case 3: case 3:
title = "Contributors"; title = "Contributors";
ADD_ATEXT("\\L\\c0"" See https://stella-emu.github.io/credits.html for"); ADD_ATEXT("\\L\\c0""See https://stella-emu.github.io/credits.html for");
ADD_ATEXT("\\L\\c0"" people that have contributed to Stella."); ADD_ATEXT("\\L\\c0""people that have contributed to Stella.");
ADD_ALINE(); ADD_ALINE();
ADD_ATEXT("\\L\\c0"" Thanks to the ScummVM project for the GUI code."); ADD_ATEXT("\\L\\c0""Thanks to the ScummVM project for the GUI code.");
ADD_ALINE(); ADD_ALINE();
ADD_ATEXT("\\L\\c0"" Thanks to Ian Bogost and the Georgia Tech"); ADD_ATEXT("\\L\\c0""Thanks to Ian Bogost and the Georgia Tech Atari Team");
ADD_ATEXT("\\L\\c0"" Atari Team for the CRT Simulation effects."); ADD_ATEXT("\\L\\c0""for the CRT Simulation effects.");
break; break;
case 4: case 4:

View File

@ -35,8 +35,11 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font) const GUI::Font& font)
: Dialog(osystem, parent) : Dialog(osystem, parent, font, "Audio settings")
{ {
const int VBORDER = 10;
const int HBORDER = 10;
const int INDENT = 20;
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth(), fontWidth = font.getMaxCharWidth(),
fontHeight = font.getFontHeight(), fontHeight = font.getFontHeight(),
@ -49,22 +52,24 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent,
VariantList items; VariantList items;
// Set real dimensions // Set real dimensions
_w = 35 * fontWidth + 10; _w = 35 * fontWidth + HBORDER * 2;
_h = 7 * (lineHeight + 4) + 10; _h = 7 * (lineHeight + 4) + VBORDER + _th;
xpos = HBORDER; ypos = VBORDER + _th;
// Enable sound
xpos = HBORDER;
mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos, ypos,
"Enable sound", kSoundEnableChanged);
wid.push_back(mySoundEnableCheckbox);
ypos += lineHeight + 4;
xpos += INDENT;
// Volume // Volume
xpos = 3 * fontWidth; ypos = 10; myVolumeSlider = new SliderWidget(this, font, xpos, ypos, 11 * fontWidth + 5, lineHeight,
"Volume ", lwidth, 0, 4 * fontWidth, "%");
myVolumeSlider = new SliderWidget(this, font, xpos, ypos, 6*fontWidth, lineHeight,
"Volume ", lwidth, kVolumeChanged);
myVolumeSlider->setMinValue(1); myVolumeSlider->setMaxValue(100); myVolumeSlider->setMinValue(1); myVolumeSlider->setMaxValue(100);
wid.push_back(myVolumeSlider); wid.push_back(myVolumeSlider);
myVolumeLabel = new StaticTextWidget(this, font,
xpos + myVolumeSlider->getWidth() + 4,
ypos + 1,
3*fontWidth, fontHeight, "", TextAlign::Left);
myVolumeLabel->setFlags(WIDGET_CLEARBG);
ypos += lineHeight + 4; ypos += lineHeight + 4;
// Fragment size // Fragment size
@ -75,7 +80,7 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent,
VarList::push_back(items, "2 KB", "2048"); VarList::push_back(items, "2 KB", "2048");
VarList::push_back(items, "4 KB", "4096"); VarList::push_back(items, "4 KB", "4096");
myFragsizePopup = new PopUpWidget(this, font, xpos, ypos, myFragsizePopup = new PopUpWidget(this, font, xpos, ypos,
pwidth + myVolumeLabel->getWidth() - 4, lineHeight, pwidth, lineHeight,
items, "Sample size (*) ", lwidth); items, "Sample size (*) ", lwidth);
wid.push_back(myFragsizePopup); wid.push_back(myFragsizePopup);
ypos += lineHeight + 4; ypos += lineHeight + 4;
@ -88,31 +93,19 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent,
VarList::push_back(items, "44100 Hz", "44100"); VarList::push_back(items, "44100 Hz", "44100");
VarList::push_back(items, "48000 Hz", "48000"); VarList::push_back(items, "48000 Hz", "48000");
myFreqPopup = new PopUpWidget(this, font, xpos, ypos, myFreqPopup = new PopUpWidget(this, font, xpos, ypos,
pwidth + myVolumeLabel->getWidth() - 4, lineHeight, pwidth, lineHeight,
items, "Frequency (*) ", lwidth); items, "Frequency (*) ", lwidth);
wid.push_back(myFreqPopup); wid.push_back(myFreqPopup);
ypos += lineHeight + 4;
// Enable sound
xpos = (_w - (font.getStringWidth("Enable sound") + 10)) / 2;
ypos += 4;
mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos, ypos,
"Enable sound", kSoundEnableChanged);
wid.push_back(mySoundEnableCheckbox);
// Add message concerning usage // Add message concerning usage
ypos += lineHeight + 12; ypos = _h - fontHeight * 2 - 24;
const GUI::Font& infofont = instance().frameBuffer().infoFont(); const GUI::Font& infofont = instance().frameBuffer().infoFont();
new StaticTextWidget(this, infofont, 10, ypos, new StaticTextWidget(this, infofont, HBORDER, ypos,
font.getStringWidth("(*) Requires application restart"), fontHeight, font.getStringWidth("(*) Requires application restart"), fontHeight,
"(*) Requires application restart", TextAlign::Left); "(*) Requires application restart", TextAlign::Left);
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
ButtonWidget* b; addDefaultsOKCancelBGroup(wid, font);
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font);
addToFocusList(wid); addToFocusList(wid);
} }
@ -122,7 +115,6 @@ void AudioDialog::loadConfig()
{ {
// Volume // Volume
myVolumeSlider->setValue(instance().settings().getInt("volume")); myVolumeSlider->setValue(instance().settings().getInt("volume"));
myVolumeLabel->setLabel(instance().settings().getString("volume"));
// Fragsize // Fragsize
myFragsizePopup->setSelected(instance().settings().getString("fragsize"), "512"); myFragsizePopup->setSelected(instance().settings().getString("fragsize"), "512");
@ -166,7 +158,6 @@ void AudioDialog::saveConfig()
void AudioDialog::setDefaults() void AudioDialog::setDefaults()
{ {
myVolumeSlider->setValue(100); myVolumeSlider->setValue(100);
myVolumeLabel->setLabel("100");
myFragsizePopup->setSelected("512", ""); myFragsizePopup->setSelected("512", "");
myFreqPopup->setSelected("31400", ""); myFreqPopup->setSelected("31400", "");
@ -183,7 +174,6 @@ void AudioDialog::setDefaults()
void AudioDialog::handleSoundEnableChange(bool active) void AudioDialog::handleSoundEnableChange(bool active)
{ {
myVolumeSlider->setEnabled(active); myVolumeSlider->setEnabled(active);
myVolumeLabel->setEnabled(active);
myFragsizePopup->setEnabled(active); myFragsizePopup->setEnabled(active);
myFreqPopup->setEnabled(active); myFreqPopup->setEnabled(active);
} }
@ -203,10 +193,6 @@ void AudioDialog::handleCommand(CommandSender* sender, int cmd,
setDefaults(); setDefaults();
break; break;
case kVolumeChanged:
myVolumeLabel->setValue(myVolumeSlider->getValue());
break;
case kSoundEnableChanged: case kSoundEnableChanged:
handleSoundEnableChange(data == 1); handleSoundEnableChange(data == 1);
break; break;

View File

@ -45,12 +45,10 @@ class AudioDialog : public Dialog
private: private:
enum { enum {
kVolumeChanged = 'ADvc',
kSoundEnableChanged = 'ADse' kSoundEnableChanged = 'ADse'
}; };
SliderWidget* myVolumeSlider; SliderWidget* myVolumeSlider;
StaticTextWidget* myVolumeLabel;
PopUpWidget* myFragsizePopup; PopUpWidget* myFragsizePopup;
PopUpWidget* myFreqPopup; PopUpWidget* myFreqPopup;
CheckboxWidget* mySoundEnableCheckbox; CheckboxWidget* mySoundEnableCheckbox;

View File

@ -33,8 +33,8 @@
*/ */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font, BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font,
int max_w, int max_h) int max_w, int max_h, const string& title)
: Dialog(boss->instance(), boss->parent()), : Dialog(boss->instance(), boss->parent(), font, title),
CommandSender(boss), CommandSender(boss),
_cmd(0), _cmd(0),
_mode(FileSave) _mode(FileSave)
@ -46,38 +46,31 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font,
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
buttonWidth = font.getStringWidth("Defaults") + 20, buttonWidth = font.getStringWidth("Defaults") + 20,
buttonHeight = font.getLineHeight() + 4, buttonHeight = font.getLineHeight() + 4,
selectHeight = lineHeight + 8; selectHeight = lineHeight + 12;
int xpos, ypos; int xpos, ypos;
ButtonWidget* b; ButtonWidget* b;
xpos = 10; ypos = 4; xpos = 10; ypos = 4 + _th;
_title = new StaticTextWidget(this, font, xpos, ypos,
_w - 2 * xpos, lineHeight,
"", TextAlign::Center);
// Current path - TODO: handle long paths ? // Current path - TODO: handle long paths ?
ypos += lineHeight + 4; StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos + 2, "Pfad ");
_currentPath = new StaticTextWidget(this, font, xpos, ypos, _currentPath = new EditTextWidget(this, font, xpos + t->getWidth(), ypos,
_w - 2 * xpos, lineHeight, _w - t->getWidth() - 2 * xpos, lineHeight);
"", TextAlign::Left); _currentPath->setEditable(false);
// Add file list // Add file list
ypos += lineHeight + 4; ypos += lineHeight + 8;
_fileList = new FileListWidget(this, font, xpos, ypos, _w - 2 * xpos, _fileList = new FileListWidget(this, font, xpos, ypos, _w - 2 * xpos,
_h - selectHeight - buttonHeight - ypos - 20); _h - selectHeight - buttonHeight - ypos - 20);
_fileList->setEditable(false); _fileList->setEditable(false);
addFocusWidget(_fileList); addFocusWidget(_fileList);
// Add currently selected item // Add currently selected item
ypos += _fileList->getHeight() + 4; ypos += _fileList->getHeight() + 8;
_type = new StaticTextWidget(this, font, xpos, ypos+2, _type = new StaticTextWidget(this, font, xpos, ypos + 2, "Name ");
font.getStringWidth("Name "), lineHeight,
"Name", TextAlign::Center);
_selected = new EditTextWidget(this, font, xpos + _type->getWidth(), ypos, _selected = new EditTextWidget(this, font, xpos + _type->getWidth(), ypos,
_w - _type->getWidth() - 2 * xpos, lineHeight, ""); _w - _type->getWidth() - 2 * xpos, lineHeight, "");
_selected->setEditable(false); _selected->setEditable(false);
addFocusWidget(_selected);
// Buttons // Buttons
_goUpButton = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, _goUpButton = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
@ -111,11 +104,10 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BrowserDialog::show(const string& title, const string& startpath, void BrowserDialog::show(const string& startpath,
BrowserDialog::ListMode mode, int cmd, BrowserDialog::ListMode mode, int cmd,
const string& ext) const string& ext)
{ {
_title->setLabel(title);
_cmd = cmd; _cmd = cmd;
_mode = mode; _mode = mode;
@ -125,17 +117,23 @@ void BrowserDialog::show(const string& title, const string& startpath,
_fileList->setFileListMode(FilesystemNode::kListAll); _fileList->setFileListMode(FilesystemNode::kListAll);
_fileList->setFileExtension(ext); _fileList->setFileExtension(ext);
_selected->setEditable(false); _selected->setEditable(false);
_selected->clearFlags(WIDGET_INVISIBLE);
_type->clearFlags(WIDGET_INVISIBLE);
break; break;
case FileSave: case FileSave:
_fileList->setFileListMode(FilesystemNode::kListAll); _fileList->setFileListMode(FilesystemNode::kListAll);
_fileList->setFileExtension(ext); _fileList->setFileExtension(ext);
_selected->setEditable(false); // FIXME - disable user input for now _selected->setEditable(false); // FIXME - disable user input for now
_selected->clearFlags(WIDGET_INVISIBLE);
_type->clearFlags(WIDGET_INVISIBLE);
break; break;
case Directories: case Directories:
_fileList->setFileListMode(FilesystemNode::kListDirectoriesOnly); _fileList->setFileListMode(FilesystemNode::kListDirectoriesOnly);
_selected->setEditable(false); _selected->setEditable(false);
_selected->setFlags(WIDGET_INVISIBLE);
_type->setFlags(WIDGET_INVISIBLE);
break; break;
} }
@ -164,7 +162,7 @@ void BrowserDialog::updateUI()
_goUpButton->setEnabled(_fileList->currentDir().hasParent()); _goUpButton->setEnabled(_fileList->currentDir().hasParent());
// Update the path display // Update the path display
_currentPath->setLabel(_fileList->currentDir().getShortPath()); _currentPath->setText(_fileList->currentDir().getShortPath());
// Enable/disable OK button based on current mode // Enable/disable OK button based on current mode
bool enable = _mode == Directories || !_fileList->selected().isDirectory(); bool enable = _mode == Directories || !_fileList->selected().isDirectory();

View File

@ -39,11 +39,12 @@ class BrowserDialog : public Dialog, public CommandSender
}; };
public: public:
BrowserDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h); BrowserDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h,
const string& title = "");
virtual ~BrowserDialog() = default; virtual ~BrowserDialog() = default;
/** Place the browser window onscreen, using the given attributes */ /** Place the browser window onscreen, using the given attributes */
void show(const string& title, const string& startpath, void show(const string& startpath,
BrowserDialog::ListMode mode, int cmd, const string& ext = ""); BrowserDialog::ListMode mode, int cmd, const string& ext = "");
/** Get resulting file node (called after receiving kChooseCmd) */ /** Get resulting file node (called after receiving kChooseCmd) */
@ -63,8 +64,7 @@ class BrowserDialog : public Dialog, public CommandSender
int _cmd; int _cmd;
FileListWidget* _fileList; FileListWidget* _fileList;
StaticTextWidget* _currentPath; EditTextWidget* _currentPath;
StaticTextWidget* _title;
StaticTextWidget* _type; StaticTextWidget* _type;
EditTextWidget* _selected; EditTextWidget* _selected;
ButtonWidget* _goUpButton; ButtonWidget* _goUpButton;

View File

@ -47,6 +47,20 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font,
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CheckListWidget::handleMouseEntered()
{
setFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CheckListWidget::handleMouseLeft()
{
clearFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CheckListWidget::setList(const StringList& list, const BoolArray& state) void CheckListWidget::setList(const StringList& list, const BoolArray& state)
{ {
@ -85,10 +99,7 @@ void CheckListWidget::drawWidget(bool hilite)
int i, pos, len = int(_list.size()); int i, pos, len = int(_list.size());
// Draw a thin frame around the list and to separate columns // Draw a thin frame around the list and to separate columns
s.hLine(_x, _y, _x + _w - 1, kColor); s.frameRect(_x, _y, _w, _h, hilite ? kWidColorHi : kColor);
s.hLine(_x, _y + _h - 1, _x + _w - 1, kShadowColor);
s.vLine(_x, _y, _y + _h - 1, kColor);
s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor); s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor);
// Draw the list items // Draw the list items

View File

@ -37,13 +37,16 @@ class CheckListWidget : public ListWidget
int x, int y, int w, int h); int x, int y, int w, int h);
virtual ~CheckListWidget() = default; virtual ~CheckListWidget() = default;
void setStyle(CheckStyle style);
void setList(const StringList& list, const BoolArray& state); void setList(const StringList& list, const BoolArray& state);
void setLine(int line, const string& str, const bool& state); void setLine(int line, const string& str, const bool& state);
bool getState(int line); bool getState(int line);
bool getSelectedState() { return getState(_selectedItem); } bool getSelectedState() { return getState(_selectedItem); }
protected:
void handleMouseEntered() override;
void handleMouseLeft() override;
private: private:
bool handleEvent(Event::Type e) override; bool handleEvent(Event::Type e) override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override;

View File

@ -48,14 +48,7 @@ void ColorWidget::drawWidget(bool hilite)
FBSurface& s = dialog().surface(); FBSurface& s = dialog().surface();
// Draw a thin frame around us. // Draw a thin frame around us.
#ifndef FLAT_UI
s.hLine(_x, _y, _x + _w - 1, kColor);
s.hLine(_x, _y +_h, _x + _w - 1, kShadowColor);
s.vLine(_x, _y, _y+_h, kColor);
s.vLine(_x + _w - 1, _y, _y +_h - 1, kShadowColor);
#else
s.frameRect(_x, _y, _w, _h + 1, kColor); s.frameRect(_x, _y, _w, _h + 1, kColor);
#endif
// Show the currently selected color // Show the currently selected color
s.fillRect(_x+1, _y+1, _w-2, _h-1, isEnabled() ? _color : kWidColor); s.fillRect(_x+1, _y+1, _w-2, _h-1, isEnabled() ? _color : kWidColor);
@ -63,12 +56,7 @@ void ColorWidget::drawWidget(bool hilite)
// Cross out the grid? // Cross out the grid?
if(_crossGrid) if(_crossGrid)
{ {
#ifndef FLAT_UI
for(uInt32 row = 1; row < 4; ++row)
s.hLine(_x, _y + (row * _h/4), _x + _w - 2, kColor);
#else
s.line(_x + 1, _y + 1, _x + _w - 2, _y + _h - 1, kColor); s.line(_x + 1, _y + 1, _x + _w - 2, _y + _h - 1, kColor);
s.line(_x + _w - 2, _y + 1, _x + 1, _y + _h - 1, kColor); s.line(_x + _w - 2, _y + 1, _x + 1, _y + _h - 1, kColor);
#endif
} }
} }

View File

@ -29,7 +29,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font, ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
const VariantList& combolist) const VariantList& combolist)
: Dialog(boss->instance(), boss->parent()), : Dialog(boss->instance(), boss->parent(), font, ""),
myComboEvent(Event::NoType) myComboEvent(Event::NoType)
{ {
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
@ -42,19 +42,15 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
// Set real dimensions // Set real dimensions
_w = 35 * fontWidth + 10; _w = 35 * fontWidth + 10;
_h = 11 * (lineHeight + 4) + 10; _h = 10 * (lineHeight + 4) + 10 + _th;
xpos = ypos = 5; xpos = 10;
ypos = 10 + _th;
// Get maximum width of popupwidget // Get maximum width of popupwidget
int pwidth = 0; int pwidth = 0;
for(const auto& s: combolist) for(const auto& s: combolist)
pwidth = std::max(font.getStringWidth(s.first), pwidth); pwidth = std::max(font.getStringWidth(s.first), pwidth);
// Label for dialog, indicating which combo is being changed
myComboName = new StaticTextWidget(this, font, xpos, ypos, _w - xpos - 10,
fontHeight, "", TextAlign::Center);
ypos += (lineHeight + 4) + 5;
// Add event popup for 8 events // Add event popup for 8 events
auto ADD_EVENT_POPUP = [&](int idx, const string& label) auto ADD_EVENT_POPUP = [&](int idx, const string& label)
{ {
@ -75,11 +71,7 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
myEvents[7] = nullptr; ADD_EVENT_POPUP(7, "Event 8 "); myEvents[7] = nullptr; ADD_EVENT_POPUP(7, "Event 8 ");
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
ButtonWidget* b; addDefaultsOKCancelBGroup(wid, font);
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font);
addToFocusList(wid); addToFocusList(wid);
} }
@ -91,7 +83,7 @@ void ComboDialog::show(Event::Type event, const string& name)
if(event >= Event::Combo1 && event <= Event::Combo16) if(event >= Event::Combo1 && event <= Event::Combo16)
{ {
myComboEvent = event; myComboEvent = event;
myComboName->setLabel("Add events for " + name); setTitle("Add events for " + name);
open(); open();
} }
else else

View File

@ -45,7 +45,6 @@ class ComboDialog : public Dialog
private: private:
Event::Type myComboEvent; Event::Type myComboEvent;
StaticTextWidget* myComboName;
PopUpWidget* myEvents[8]; PopUpWidget* myEvents[8];
private: private:

View File

@ -30,23 +30,25 @@ CommandDialog::CommandDialog(OSystem& osystem, DialogContainer& parent)
: Dialog(osystem, parent) : Dialog(osystem, parent)
{ {
const GUI::Font& font = instance().frameBuffer().font(); const GUI::Font& font = instance().frameBuffer().font();
initTitle(font, "Commands");
const int buttonWidth = font.getStringWidth("Right Diff B") + 20, const int buttonWidth = font.getStringWidth("Right Diff B") + 20,
buttonHeight = font.getLineHeight() + 6, buttonHeight = font.getLineHeight() + 6,
rowHeight = font.getLineHeight() + 10; rowHeight = buttonHeight + 8;
// Set real dimensions // Set real dimensions
_w = 3 * (buttonWidth + 5) + 20; _w = 3 * (buttonWidth + 5) + 20;
_h = 6 * rowHeight + 15; _h = 6 * rowHeight + 8 + _th;
WidgetArray wid; WidgetArray wid;
ButtonWidget* b[16]; ButtonWidget* b[16];
int xoffset = 10, yoffset = 10; int xoffset = 10, yoffset = 8 + _th;
auto ADD_CD_BUTTON = [&](const string& label, int cmd) auto ADD_CD_BUTTON = [&](const string& label, int cmd)
{ {
ButtonWidget* bw = new ButtonWidget(this, font, xoffset, yoffset, ButtonWidget* bw = new ButtonWidget(this, font, xoffset, yoffset,
buttonWidth, buttonHeight, label, cmd); buttonWidth, buttonHeight, label, cmd);
xoffset += buttonWidth + 6; xoffset += buttonWidth + 8;
return bw; return bw;
}; };
@ -56,31 +58,31 @@ CommandDialog::CommandDialog(OSystem& osystem, DialogContainer& parent)
b[8] = ADD_CD_BUTTON("Save State", kSaveStateCmd); b[8] = ADD_CD_BUTTON("Save State", kSaveStateCmd);
// Row 2 // Row 2
xoffset = 10; yoffset += buttonHeight + 3; xoffset = 10; yoffset += buttonHeight + 8;
b[1] = ADD_CD_BUTTON("Reset", kResetCmd); b[1] = ADD_CD_BUTTON("Reset", kResetCmd);
b[5] = ADD_CD_BUTTON("Left Diff B", kLeftDiffBCmd); b[5] = ADD_CD_BUTTON("Left Diff B", kLeftDiffBCmd);
b[9] = ADD_CD_BUTTON("State Slot", kStateSlotCmd); b[9] = ADD_CD_BUTTON("State Slot", kStateSlotCmd);
// Row 3 // Row 3
xoffset = 10; yoffset += buttonHeight + 3; xoffset = 10; yoffset += buttonHeight + 8;
b[2] = ADD_CD_BUTTON("Color TV", kColorCmd); b[2] = ADD_CD_BUTTON("Color TV", kColorCmd);
b[6] = ADD_CD_BUTTON("Right Diff A", kRightDiffACmd); b[6] = ADD_CD_BUTTON("Right Diff A", kRightDiffACmd);
b[10] = ADD_CD_BUTTON("Load State", kLoadStateCmd); b[10] = ADD_CD_BUTTON("Load State", kLoadStateCmd);
// Row 4 // Row 4
xoffset = 10; yoffset += buttonHeight + 3; xoffset = 10; yoffset += buttonHeight + 8;
b[3] = ADD_CD_BUTTON("B/W TV", kBWCmd); b[3] = ADD_CD_BUTTON("B/W TV", kBWCmd);
b[7] = ADD_CD_BUTTON("Right Diff B", kRightDiffBCmd); b[7] = ADD_CD_BUTTON("Right Diff B", kRightDiffBCmd);
b[11] = ADD_CD_BUTTON("Snapshot", kSnapshotCmd); b[11] = ADD_CD_BUTTON("Snapshot", kSnapshotCmd);
// Row 5 // Row 5
xoffset = 10; yoffset += buttonHeight + 3; xoffset = 10; yoffset += buttonHeight + 8;
b[12] = ADD_CD_BUTTON("NTSC/PAL", kFormatCmd); b[12] = ADD_CD_BUTTON("TV Format", kFormatCmd);
b[13] = ADD_CD_BUTTON("Palette", kPaletteCmd); b[13] = ADD_CD_BUTTON("Palette", kPaletteCmd);
b[14] = ADD_CD_BUTTON("Reload ROM", kReloadRomCmd); b[14] = ADD_CD_BUTTON("Reload ROM", kReloadRomCmd);
// Row 6 // Row 6
xoffset = 10 + buttonWidth + 6; yoffset += buttonHeight + 3; xoffset = 10 + buttonWidth + 8; yoffset += buttonHeight + 8;
b[15] = ADD_CD_BUTTON("Exit Game", kExitCmd); b[15] = ADD_CD_BUTTON("Exit Game", kExitCmd);
for(int i = 0; i < 16; ++i) for(int i = 0; i < 16; ++i)

View File

@ -29,94 +29,92 @@
ConfigPathDialog::ConfigPathDialog( ConfigPathDialog::ConfigPathDialog(
OSystem& osystem, DialogContainer& parent, OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, GuiObject* boss) const GUI::Font& font, GuiObject* boss)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "Configure paths"),
CommandSender(boss), CommandSender(boss),
myFont(font), myFont(font),
myBrowser(nullptr), myBrowser(nullptr),
myIsGlobal(boss != nullptr) myIsGlobal(boss != nullptr)
{ {
const int VBORDER = 10 + _th;
const int HBORDER = 10;
const int V_GAP = 4;
const int H_GAP = 8;
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth(), fontWidth = font.getMaxCharWidth(),
buttonWidth = font.getStringWidth("Properties file") + 20, buttonWidth = font.getStringWidth("Properties file") + 20,
buttonHeight = font.getLineHeight() + 4; buttonHeight = font.getLineHeight() + 4;
const int vBorder = 8;
const int hBorder = 10;
int xpos, ypos; int xpos, ypos;
WidgetArray wid; WidgetArray wid;
ButtonWidget* b; ButtonWidget* b;
// Set real dimensions // Set real dimensions
_w = 56 * fontWidth + 8; _w = 64 * fontWidth + HBORDER*2;
_h = 9 * (lineHeight + 4) + 10; _h = 9 * (lineHeight + V_GAP) + VBORDER;
xpos = hBorder; ypos = vBorder; xpos = HBORDER; ypos = VBORDER;
// ROM path // ROM path
ButtonWidget* romButton = ButtonWidget* romButton =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"ROM path" + ELLIPSIS, kChooseRomDirCmd); "ROM path" + ELLIPSIS, kChooseRomDirCmd);
wid.push_back(romButton); wid.push_back(romButton);
xpos += buttonWidth + 10; xpos += buttonWidth + H_GAP;
myRomPath = new EditTextWidget(this, font, xpos, ypos + 2, myRomPath = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(myRomPath); wid.push_back(myRomPath);
// Cheat file // Cheat file
xpos = hBorder; ypos += romButton->getHeight() + 3; xpos = HBORDER; ypos += buttonHeight + V_GAP;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Cheat file" + ELLIPSIS, kChooseCheatFileCmd); "Cheat file" + ELLIPSIS, kChooseCheatFileCmd);
wid.push_back(b); wid.push_back(b);
xpos += buttonWidth + 10; xpos += buttonWidth + H_GAP;
myCheatFile = new EditTextWidget(this, font, xpos, ypos + 2, myCheatFile = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(myCheatFile); wid.push_back(myCheatFile);
// Palette file // Palette file
xpos = hBorder; ypos += b->getHeight() + 3; xpos = HBORDER; ypos += buttonHeight + V_GAP;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Palette file" + ELLIPSIS, kChoosePaletteFileCmd); "Palette file" + ELLIPSIS, kChoosePaletteFileCmd);
wid.push_back(b); wid.push_back(b);
xpos += buttonWidth + 10; xpos += buttonWidth + H_GAP;
myPaletteFile = new EditTextWidget(this, font, xpos, ypos + 2, myPaletteFile = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(myPaletteFile); wid.push_back(myPaletteFile);
// Properties file // Properties file
xpos = hBorder; ypos += b->getHeight() + 3; xpos = HBORDER; ypos += buttonHeight + V_GAP;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Properties file" + ELLIPSIS, kChoosePropsFileCmd); "Properties file" + ELLIPSIS, kChoosePropsFileCmd);
wid.push_back(b); wid.push_back(b);
xpos += buttonWidth + 10; xpos += buttonWidth + H_GAP;
myPropsFile = new EditTextWidget(this, font, xpos, ypos + 2, myPropsFile = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(myPropsFile); wid.push_back(myPropsFile);
// State directory // State directory
xpos = hBorder; ypos += b->getHeight() + 3; xpos = HBORDER; ypos += buttonHeight + V_GAP;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"State path" + ELLIPSIS, kChooseStateDirCmd); "State path" + ELLIPSIS, kChooseStateDirCmd);
wid.push_back(b); wid.push_back(b);
xpos += buttonWidth + 10; xpos += buttonWidth + H_GAP;
myStatePath = new EditTextWidget(this, font, xpos, ypos + 2, myStatePath = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(myStatePath); wid.push_back(myStatePath);
// NVRAM directory // NVRAM directory
xpos = hBorder; ypos += b->getHeight() + 3; xpos = HBORDER; ypos += buttonHeight + V_GAP;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"NVRAM path" + ELLIPSIS, kChooseNVRamDirCmd); "NVRAM path" + ELLIPSIS, kChooseNVRamDirCmd);
wid.push_back(b); wid.push_back(b);
xpos += buttonWidth + 10; xpos += buttonWidth + H_GAP;
myNVRamPath = new EditTextWidget(this, font, xpos, ypos + 2, myNVRamPath = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(myNVRamPath); wid.push_back(myNVRamPath);
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, addDefaultsOKCancelBGroup(wid, font);
font.getStringWidth("Defaults") + 20, buttonHeight,
"Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font);
addToFocusList(wid); addToFocusList(wid);
@ -210,48 +208,48 @@ void ConfigPathDialog::handleCommand(CommandSender* sender, int cmd,
case kChooseRomDirCmd: case kChooseRomDirCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select ROM directory");
myBrowser->show("Select ROM directory", myRomPath->getText(), myBrowser->show(myRomPath->getText(),
BrowserDialog::Directories, LauncherDialog::kRomDirChosenCmd); BrowserDialog::Directories, LauncherDialog::kRomDirChosenCmd);
break; break;
case kChooseCheatFileCmd: case kChooseCheatFileCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select cheat file");
myBrowser->show("Select cheat file", myCheatFile->getText(), myBrowser->show(myCheatFile->getText(),
BrowserDialog::FileLoad, kCheatFileChosenCmd); BrowserDialog::FileLoad, kCheatFileChosenCmd);
break; break;
case kChoosePaletteFileCmd: case kChoosePaletteFileCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select palette file");
myBrowser->show("Select palette file", myPaletteFile->getText(), myBrowser->show(myPaletteFile->getText(),
BrowserDialog::FileLoad, kPaletteFileChosenCmd); BrowserDialog::FileLoad, kPaletteFileChosenCmd);
break; break;
case kChoosePropsFileCmd: case kChoosePropsFileCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select properties file");
myBrowser->show("Select properties file", myPropsFile->getText(), myBrowser->show(myPropsFile->getText(),
BrowserDialog::FileLoad, kPropsFileChosenCmd); BrowserDialog::FileLoad, kPropsFileChosenCmd);
break; break;
case kChooseNVRamDirCmd: case kChooseNVRamDirCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select NVRAM directory");
myBrowser->show("Select NVRAM directory", myNVRamPath->getText(), myBrowser->show(myNVRamPath->getText(),
BrowserDialog::Directories, kNVRamDirChosenCmd); BrowserDialog::Directories, kNVRamDirChosenCmd);
break; break;
case kChooseStateDirCmd: case kChooseStateDirCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select state directory");
myBrowser->show("Select state directory", myStatePath->getText(), myBrowser->show(myStatePath->getText(),
BrowserDialog::Directories, kStateDirChosenCmd); BrowserDialog::Directories, kStateDirChosenCmd);
break; break;
@ -290,7 +288,7 @@ void ConfigPathDialog::handleCommand(CommandSender* sender, int cmd,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ConfigPathDialog::createBrowser() void ConfigPathDialog::createBrowser(const string& title)
{ {
uInt32 w = 0, h = 0; uInt32 w = 0, h = 0;
getResizableBounds(w, h); getResizableBounds(w, h);
@ -298,5 +296,7 @@ void ConfigPathDialog::createBrowser()
// Create file browser dialog // Create file browser dialog
if(!myBrowser || uInt32(myBrowser->getWidth()) != w || if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
uInt32(myBrowser->getHeight()) != h) uInt32(myBrowser->getHeight()) != h)
myBrowser = make_unique<BrowserDialog>(this, myFont, w, h); myBrowser = make_unique<BrowserDialog>(this, myFont, w, h, title);
else
myBrowser->setTitle(title);
} }

View File

@ -40,7 +40,7 @@ class ConfigPathDialog : public Dialog, public CommandSender
private: private:
void handleCommand(CommandSender* sender, int cmd, int data, int id) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
void createBrowser(); void createBrowser(const string& title);
void loadConfig() override; void loadConfig() override;
void saveConfig() override; void saveConfig() override;

View File

@ -60,11 +60,7 @@ void ContextMenu::addItems(const VariantList& items)
maxwidth = std::max(maxwidth, _font.getStringWidth(e.first)); maxwidth = std::max(maxwidth, _font.getStringWidth(e.first));
_x = _y = 0; _x = _y = 0;
#ifndef FLAT_UI
_w = maxwidth + 15;
#else
_w = maxwidth + 23; _w = maxwidth + 23;
#endif
_h = 1; // recalculate this in ::recalc() _h = 1; // recalculate this in ::recalc()
_scrollUpColor = _firstEntry > 0 ? kScrollColor : kColor; _scrollUpColor = _firstEntry > 0 ? kScrollColor : kColor;
@ -106,18 +102,18 @@ void ContextMenu::recalc(const GUI::Rect& image)
{ {
// Now is the time to adjust the height // Now is the time to adjust the height
// If it's higher than the screen, we need to scroll through // If it's higher than the screen, we need to scroll through
uInt32 maxentries = std::min(18u, (image.height() - 4) / _rowHeight); uInt32 maxentries = std::min(18u, (image.height() - 2) / _rowHeight);
if(_entries.size() > maxentries) if(_entries.size() > maxentries)
{ {
// We show two less than the max, so we have room for two scroll buttons // We show two less than the max, so we have room for two scroll buttons
_numEntries = maxentries - 2; _numEntries = maxentries - 2;
_h = maxentries * _rowHeight + 4; _h = maxentries * _rowHeight + 2;
_showScroll = true; _showScroll = true;
} }
else else
{ {
_numEntries = int(_entries.size()); _numEntries = int(_entries.size());
_h = int(_entries.size()) * _rowHeight + 4; _h = int(_entries.size()) * _rowHeight + 2;
_showScroll = false; _showScroll = false;
} }
_isScrolling = false; _isScrolling = false;
@ -555,23 +551,16 @@ void ContextMenu::drawDialog()
{ {
// Draw menu border and background // Draw menu border and background
s.fillRect(_x+1, _y+1, _w-2, _h-2, kWidColor); s.fillRect(_x+1, _y+1, _w-2, _h-2, kWidColor);
#ifndef FLAT_UI
s.box(_x, _y, _w, _h, kColor, kShadowColor);
// Draw the entries, taking scroll buttons into account
int x = _x + 2, y = _y + 2, w = _w - 4;
#else
s.frameRect(_x, _y, _w, _h, kTextColor); s.frameRect(_x, _y, _w, _h, kTextColor);
// Draw the entries, taking scroll buttons into account // Draw the entries, taking scroll buttons into account
int x = _x + 1, y = _y + 1, w = _w - 2; int x = _x + 1, y = _y + 1, w = _w - 2;
#endif
// Show top scroll area // Show top scroll area
int offset = _selectedOffset; int offset = _selectedOffset;
if(_showScroll) if(_showScroll)
{ {
s.hLine(x, y+_rowHeight-1, w+2, kShadowColor); s.hLine(x, y+_rowHeight-1, w+2, kColor);
s.drawBitmap(up_arrow, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollUpColor, 8); s.drawBitmap(up_arrow, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollUpColor, 8);
y += _rowHeight; y += _rowHeight;
offset--; offset--;
@ -582,14 +571,14 @@ void ContextMenu::drawDialog()
bool hilite = offset == current; bool hilite = offset == current;
if(hilite) s.fillRect(x, y, w, _rowHeight, kTextColorHi); if(hilite) s.fillRect(x, y, w, _rowHeight, kTextColorHi);
s.drawString(_font, _entries[i].first, x + 1, y + 2, w, s.drawString(_font, _entries[i].first, x + 1, y + 2, w,
!hilite ? kTextColor : kWidColor); !hilite ? kTextColor : kTextColorInv);
y += _rowHeight; y += _rowHeight;
} }
// Show bottom scroll area // Show bottom scroll area
if(_showScroll) if(_showScroll)
{ {
s.hLine(x, y, w+2, kShadowColor); s.hLine(x, y, w+2, kColor);
s.drawBitmap(down_arrow, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, 8); s.drawBitmap(down_arrow, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, 8);
} }

View File

@ -23,7 +23,6 @@
#include "SaveKey.hxx" #include "SaveKey.hxx"
#include "AtariVox.hxx" #include "AtariVox.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include "EventMappingWidget.hxx"
#include "EditTextWidget.hxx" #include "EditTextWidget.hxx"
#include "PopUpWidget.hxx" #include "PopUpWidget.hxx"
#include "RadioButtonWidget.hxx" #include "RadioButtonWidget.hxx"
@ -45,7 +44,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DeveloperDialog::DeveloperDialog(OSystem& osystem, DialogContainer& parent, DeveloperDialog::DeveloperDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h) const GUI::Font& font, int max_w, int max_h)
: Dialog(osystem, parent) : Dialog(osystem, parent, font, "Developer settings")
{ {
const int VGAP = 4; const int VGAP = 4;
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
@ -55,18 +54,21 @@ DeveloperDialog::DeveloperDialog(OSystem& osystem, DialogContainer& parent,
// Set real dimensions // Set real dimensions
_w = std::min(53 * fontWidth + 10, max_w); _w = std::min(53 * fontWidth + 10, max_w);
_h = std::min(15 * (lineHeight + VGAP) + 14, max_h); _h = std::min(15 * (lineHeight + VGAP) + 14 + _th, max_h);
// The tab widget // The tab widget
xpos = 2; ypos = 4; xpos = 2; ypos = 4;
myTab = new TabWidget(this, font, xpos, ypos, _w - 2 * xpos, _h - buttonHeight - 16 - ypos); myTab = new TabWidget(this, font, xpos, ypos + _th, _w - 2 * xpos, _h - _th - buttonHeight - 16 - ypos);
addTabWidget(myTab); addTabWidget(myTab);
addEmulationTab(font); addEmulationTab(font);
addVideoTab(font); addVideoTab(font);
addTimeMachineTab(font); addTimeMachineTab(font);
addDebuggerTab(font); addDebuggerTab(font);
addDefaultOKCancelButtons(font);
WidgetArray wid;
addDefaultsOKCancelBGroup(wid, font);
addBGroupToFocusList(wid);
// Activate the first tab // Activate the first tab
myTab->setActiveTab(0); myTab->setActiveTab(0);
@ -83,7 +85,7 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
int lineHeight = font.getLineHeight(); int lineHeight = font.getLineHeight();
WidgetArray wid; WidgetArray wid;
VariantList items; VariantList items;
int tabID = myTab->addTab(" Emulation "); int tabID = myTab->addTab("Emulation");
// settings set // settings set
mySettingsGroup0 = new RadioButtonGroup(); mySettingsGroup0 = new RadioButtonGroup();
@ -154,6 +156,12 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
myThumbExceptionWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, myThumbExceptionWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
"Fatal ARM emulation error throws exception"); "Fatal ARM emulation error throws exception");
wid.push_back(myThumbExceptionWidget); wid.push_back(myThumbExceptionWidget);
ypos += lineHeight + VGAP;
// AtariVox/SaveKey EEPROM access
myEEPROMAccessWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
"Display AtariVox/SaveKey EEPROM R/W access");
wid.push_back(myEEPROMAccessWidget);
// Add items for tab 0 // Add items for tab 0
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
@ -195,15 +203,13 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font)
wid.push_back(myTVJitterWidget); wid.push_back(myTVJitterWidget);
myTVJitterRecWidget = new SliderWidget(myTab, font, myTVJitterRecWidget = new SliderWidget(myTab, font,
myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1, myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1,
8 * fontWidth, lineHeight, "Recovery ", "Recovery ", 0, kTVJitterChanged);
font.getStringWidth("Recovery "), kTVJitterChanged);
myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20); myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20);
wid.push_back(myTVJitterRecWidget); wid.push_back(myTVJitterRecWidget);
myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font, myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font,
myTVJitterRecWidget->getRight() + 4, myTVJitterRecWidget->getRight() + 4,
myTVJitterRecWidget->getTop() + 2, myTVJitterRecWidget->getTop() + 2,
5 * fontWidth, fontHeight, "", TextAlign::Left); 5 * fontWidth, fontHeight, "");
wid.push_back(myTVJitterRecLabelWidget);
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;
myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
@ -304,8 +310,10 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font)
const int VBORDER = 8; const int VBORDER = 8;
const int VGAP = 4; const int VGAP = 4;
int ypos = VBORDER; int ypos = VBORDER;
int lineHeight = font.getLineHeight(); int lineHeight = font.getLineHeight(),
int fontHeight = font.getFontHeight(); fontHeight = font.getFontHeight(),
fontWidth = font.getMaxCharWidth(),
lwidth = fontWidth * 11;
WidgetArray wid; WidgetArray wid;
VariantList items; VariantList items;
int tabID = myTab->addTab("Time Machine"); int tabID = myTab->addTab("Time Machine");
@ -326,25 +334,21 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font)
wid.push_back(myTimeMachineWidget); wid.push_back(myTimeMachineWidget);
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;
int sWidth = font.getMaxCharWidth() * 8; int swidth = fontWidth * 12 + 5; // width of PopUpWidgets below
myStateSizeWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, sWidth, lineHeight, myStateSizeWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, swidth, lineHeight,
"Buffer size (*) ", 0, kSizeChanged); "Buffer size (*) ", 0, kSizeChanged, lwidth, " states");
myStateSizeWidget->setMinValue(20); myStateSizeWidget->setMinValue(20);
myStateSizeWidget->setMaxValue(1000); myStateSizeWidget->setMaxValue(1000);
myStateSizeWidget->setStepValue(20); myStateSizeWidget->setStepValue(20);
wid.push_back(myStateSizeWidget); wid.push_back(myStateSizeWidget);
myStateSizeLabelWidget = new StaticTextWidget(myTab, font, myStateSizeWidget->getRight() + 4,
myStateSizeWidget->getTop() + 2, "100 ");
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;
myUncompressedWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, sWidth, lineHeight, myUncompressedWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, swidth, lineHeight,
"Uncompressed size ", 0, kUncompressedChanged); "Uncompressed size ", 0, kUncompressedChanged, lwidth, " states");
myUncompressedWidget->setMinValue(0); myUncompressedWidget->setMinValue(0);
myUncompressedWidget->setMaxValue(1000); myUncompressedWidget->setMaxValue(1000);
myUncompressedWidget->setStepValue(20); myUncompressedWidget->setStepValue(20);
wid.push_back(myUncompressedWidget); wid.push_back(myUncompressedWidget);
myUncompressedLabelWidget = new StaticTextWidget(myTab, font, myUncompressedWidget->getRight() + 4,
myUncompressedWidget->getTop() + 2, "50 ");
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;
items.clear(); items.clear();
@ -418,36 +422,26 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font)
ypos += lineHeight + VGAP * 4; ypos += lineHeight + VGAP * 4;
pwidth = font.getMaxCharWidth() * 8;
// Debugger width and height // Debugger width and height
myDebuggerWidthSlider = new SliderWidget(myTab, font, xpos, ypos-1, pwidth, myDebuggerWidthSlider = new SliderWidget(myTab, font, xpos, ypos-1, "Debugger width (*) ",
lineHeight, "Debugger width (*) ", 0, 0, 6 * fontWidth, "px");
0, kDWidthChanged);
myDebuggerWidthSlider->setMinValue(DebuggerDialog::kSmallFontMinW); myDebuggerWidthSlider->setMinValue(DebuggerDialog::kSmallFontMinW);
myDebuggerWidthSlider->setMaxValue(ds.w); myDebuggerWidthSlider->setMaxValue(ds.w);
myDebuggerWidthSlider->setStepValue(10); myDebuggerWidthSlider->setStepValue(10);
wid.push_back(myDebuggerWidthSlider); wid.push_back(myDebuggerWidthSlider);
myDebuggerWidthLabel =
new StaticTextWidget(myTab, font,
xpos + myDebuggerWidthSlider->getWidth() + 4,
ypos + 1, 4 * fontWidth, fontHeight, "", TextAlign::Left);
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;
myDebuggerHeightSlider = new SliderWidget(myTab, font, xpos, ypos-1, pwidth, myDebuggerHeightSlider = new SliderWidget(myTab, font, xpos, ypos-1, "Debugger height (*) ",
lineHeight, "Debugger height (*) ", 0, 0, 6 * fontWidth, "px");
0, kDHeightChanged);
myDebuggerHeightSlider->setMinValue(DebuggerDialog::kSmallFontMinH); myDebuggerHeightSlider->setMinValue(DebuggerDialog::kSmallFontMinH);
myDebuggerHeightSlider->setMaxValue(ds.h); myDebuggerHeightSlider->setMaxValue(ds.h);
myDebuggerHeightSlider->setStepValue(10); myDebuggerHeightSlider->setStepValue(10);
wid.push_back(myDebuggerHeightSlider); wid.push_back(myDebuggerHeightSlider);
myDebuggerHeightLabel =
new StaticTextWidget(myTab, font,
xpos + myDebuggerHeightSlider->getWidth() + 4,
ypos + 1, 4 * fontWidth, fontHeight, "", TextAlign::Left);
ypos += lineHeight + VGAP * 4; ypos += lineHeight + VGAP * 4;
myGhostReadsTrapWidget = new CheckboxWidget(myTab, font, HBORDER, ypos + 1, myGhostReadsTrapWidget = new CheckboxWidget(myTab, font, HBORDER, ypos + 1,
"Trap on 'ghost' reads", kGhostReads); "Trap on 'ghost' reads", kGhostReads);
wid.push_back(myGhostReadsTrapWidget);
// Add message concerning usage // Add message concerning usage
const GUI::Font& infofont = instance().frameBuffer().infoFont(); const GUI::Font& infofont = instance().frameBuffer().infoFont();
@ -465,13 +459,8 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font)
if(!debuggerAvailable) if(!debuggerAvailable)
{ {
myDebuggerWidthSlider->clearFlags(WIDGET_ENABLED); myDebuggerWidthSlider->clearFlags(WIDGET_ENABLED);
myDebuggerWidthLabel->clearFlags(WIDGET_ENABLED);
myDebuggerHeightSlider->clearFlags(WIDGET_ENABLED); myDebuggerHeightSlider->clearFlags(WIDGET_ENABLED);
myDebuggerHeightLabel->clearFlags(WIDGET_ENABLED);
} }
// Add items for tab 1
addToFocusList(wid, myTab, tabID);
#else #else
new StaticTextWidget(myTab, font, 0, 20, _w - 20, font.getFontHeight(), new StaticTextWidget(myTab, font, 0, 20, _w - 20, font.getFontHeight(),
"Debugger support not included", TextAlign::Center); "Debugger support not included", TextAlign::Center);
@ -480,21 +469,6 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font)
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DeveloperDialog::addDefaultOKCancelButtons(const GUI::Font& font)
{
const int buttonWidth = font.getStringWidth("Defaults") + 20,
buttonHeight = font.getLineHeight() + 4;
WidgetArray wid;
wid.clear();
ButtonWidget* btn = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Defaults", GuiObject::kDefaultsCmd);
wid.push_back(btn);
addOKCancelBGroup(wid, font);
addBGroupToFocusList(wid);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DeveloperDialog::loadSettings(SettingsSet set) void DeveloperDialog::loadSettings(SettingsSet set)
{ {
@ -510,6 +484,8 @@ void DeveloperDialog::loadSettings(SettingsSet set)
myUndrivenPins[set] = instance().settings().getBool(prefix + "tiadriven"); myUndrivenPins[set] = instance().settings().getBool(prefix + "tiadriven");
// Thumb ARM emulation exception // Thumb ARM emulation exception
myThumbException[set] = instance().settings().getBool(prefix + "thumb.trapfatal"); myThumbException[set] = instance().settings().getBool(prefix + "thumb.trapfatal");
// AtariVox/SaveKey EEPROM access
myEEPROMAccess[set] = instance().settings().getBool(prefix + "eepromaccess");
// Debug colors // Debug colors
myDebugColors[set] = instance().settings().getBool(prefix + "debugcolors"); myDebugColors[set] = instance().settings().getBool(prefix + "debugcolors");
@ -542,6 +518,8 @@ void DeveloperDialog::saveSettings(SettingsSet set)
instance().settings().setValue(prefix + "tiadriven", myUndrivenPins[set]); instance().settings().setValue(prefix + "tiadriven", myUndrivenPins[set]);
// Thumb ARM emulation exception // Thumb ARM emulation exception
instance().settings().setValue(prefix + "thumb.trapfatal", myThumbException[set]); instance().settings().setValue(prefix + "thumb.trapfatal", myThumbException[set]);
// AtariVox/SaveKey EEPROM access
instance().settings().setValue(prefix + "eepromaccess", myEEPROMAccess[set]);
// Debug colors // Debug colors
instance().settings().setValue(prefix + "debugcolors", myDebugColors[set]); instance().settings().setValue(prefix + "debugcolors", myDebugColors[set]);
@ -577,6 +555,8 @@ void DeveloperDialog::getWidgetStates(SettingsSet set)
myUndrivenPins[set] = myUndrivenPinsWidget->getState(); myUndrivenPins[set] = myUndrivenPinsWidget->getState();
// Thumb ARM emulation exception // Thumb ARM emulation exception
myThumbException[set] = myThumbExceptionWidget->getState(); myThumbException[set] = myThumbExceptionWidget->getState();
// AtariVox/SaveKey EEPROM access
myEEPROMAccess[set] = myEEPROMAccessWidget->getState();
// Debug colors // Debug colors
myDebugColors[set] = myDebugColorsWidget->getState(); myDebugColors[set] = myDebugColorsWidget->getState();
@ -612,6 +592,8 @@ void DeveloperDialog::setWidgetStates(SettingsSet set)
myUndrivenPinsWidget->setState(myUndrivenPins[set]); myUndrivenPinsWidget->setState(myUndrivenPins[set]);
// Thumb ARM emulation exception // Thumb ARM emulation exception
myThumbExceptionWidget->setState(myThumbException[set]); myThumbExceptionWidget->setState(myThumbException[set]);
// AtariVox/SaveKey EEPROM access
myEEPROMAccessWidget->setState(myEEPROMAccess[set]);
handleConsole(); handleConsole();
@ -666,9 +648,7 @@ void DeveloperDialog::loadConfig()
w = ds.w; h = ds.h; w = ds.w; h = ds.h;
myDebuggerWidthSlider->setValue(w); myDebuggerWidthSlider->setValue(w);
myDebuggerWidthLabel->setValue(w);
myDebuggerHeightSlider->setValue(h); myDebuggerHeightSlider->setValue(h);
myDebuggerHeightLabel->setValue(h);
// Debugger font size // Debugger font size
string size = instance().settings().getString("dbg.fontsize"); string size = instance().settings().getString("dbg.fontsize");
@ -760,6 +740,8 @@ void DeveloperDialog::setDefaults()
myUndrivenPins[set] = devSettings ? true : false; myUndrivenPins[set] = devSettings ? true : false;
// Thumb ARM emulation exception // Thumb ARM emulation exception
myThumbException[set] = devSettings ? true : false; myThumbException[set] = devSettings ? true : false;
// AtariVox/SaveKey EEPROM access
myEEPROMAccess[set] = devSettings ? true : false;
setWidgetStates(set); setWidgetStates(set);
break; break;
@ -793,9 +775,7 @@ void DeveloperDialog::setDefaults()
uInt32 w = std::min(instance().frameBuffer().desktopSize().w, uInt32(DebuggerDialog::kMediumFontMinW)); uInt32 w = std::min(instance().frameBuffer().desktopSize().w, uInt32(DebuggerDialog::kMediumFontMinW));
uInt32 h = std::min(instance().frameBuffer().desktopSize().h, uInt32(DebuggerDialog::kMediumFontMinH)); uInt32 h = std::min(instance().frameBuffer().desktopSize().h, uInt32(DebuggerDialog::kMediumFontMinH));
myDebuggerWidthSlider->setValue(w); myDebuggerWidthSlider->setValue(w);
myDebuggerWidthLabel->setValue(w);
myDebuggerHeightSlider->setValue(h); myDebuggerHeightSlider->setValue(h);
myDebuggerHeightLabel->setValue(h);
myDebuggerFontSize->setSelected("medium"); myDebuggerFontSize->setSelected("medium");
myDebuggerFontStyle->setSelected("0"); myDebuggerFontStyle->setSelected("0");
@ -885,14 +865,6 @@ void DeveloperDialog::handleCommand(CommandSender* sender, int cmd, int data, in
break; break;
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
case kDWidthChanged:
myDebuggerWidthLabel->setValue(myDebuggerWidthSlider->getValue());
break;
case kDHeightChanged:
myDebuggerHeightLabel->setValue(myDebuggerHeightSlider->getValue());
break;
case kDFontSizeChanged: case kDFontSizeChanged:
handleFontSize(); handleFontSize();
break; break;
@ -965,11 +937,7 @@ void DeveloperDialog::handleTimeMachine()
bool enable = myTimeMachineWidget->getState(); bool enable = myTimeMachineWidget->getState();
myStateSizeWidget->setEnabled(enable); myStateSizeWidget->setEnabled(enable);
myStateSizeLabelWidget->setEnabled(enable);
myUncompressedWidget->setEnabled(enable); myUncompressedWidget->setEnabled(enable);
myUncompressedLabelWidget->setEnabled(enable);
myStateIntervalWidget->setEnabled(enable); myStateIntervalWidget->setEnabled(enable);
uInt32 size = myStateSizeWidget->getValue(); uInt32 size = myStateSizeWidget->getValue();
@ -994,7 +962,6 @@ void DeveloperDialog::handleSize()
if(horizon == -1) if(horizon == -1)
horizon = 0; horizon = 0;
myStateSizeLabelWidget->setValue(size);
// adapt horizon and interval // adapt horizon and interval
do do
{ {
@ -1024,8 +991,6 @@ void DeveloperDialog::handleUncompressed()
uInt32 size = myStateSizeWidget->getValue(); uInt32 size = myStateSizeWidget->getValue();
uInt32 uncompressed = myUncompressedWidget->getValue(); uInt32 uncompressed = myUncompressedWidget->getValue();
myUncompressedLabelWidget->setValue(myUncompressedWidget->getValue());
if(size < uncompressed) if(size < uncompressed)
myStateSizeWidget->setValue(uncompressed); myStateSizeWidget->setValue(uncompressed);
myStateHorizonWidget->setEnabled(myTimeMachineWidget->getState() && size > uncompressed); myStateHorizonWidget->setEnabled(myTimeMachineWidget->getState() && size > uncompressed);
@ -1223,16 +1188,10 @@ void DeveloperDialog::handleFontSize()
myDebuggerWidthSlider->setMinValue(minW); myDebuggerWidthSlider->setMinValue(minW);
if(minW > uInt32(myDebuggerWidthSlider->getValue())) if(minW > uInt32(myDebuggerWidthSlider->getValue()))
{
myDebuggerWidthSlider->setValue(minW); myDebuggerWidthSlider->setValue(minW);
myDebuggerWidthLabel->setValue(minW);
}
myDebuggerHeightSlider->setMinValue(minH); myDebuggerHeightSlider->setMinValue(minH);
if(minH > uInt32(myDebuggerHeightSlider->getValue())) if(minH > uInt32(myDebuggerHeightSlider->getValue()))
{
myDebuggerHeightSlider->setValue(minH); myDebuggerHeightSlider->setValue(minH);
myDebuggerHeightLabel->setValue(minH);
}
#endif #endif
} }

View File

@ -21,7 +21,6 @@
class OSystem; class OSystem;
class GuiObject; class GuiObject;
class TabWidget; class TabWidget;
class EventMappingWidget;
class CheckboxWidget; class CheckboxWidget;
class EditTextWidget; class EditTextWidget;
class PopUpWidget; class PopUpWidget;
@ -75,8 +74,6 @@ class DeveloperDialog : public Dialog
kPFColourChangedCmd = 'GOpf', kPFColourChangedCmd = 'GOpf',
kBLColourChangedCmd = 'GObl', kBLColourChangedCmd = 'GObl',
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
kDWidthChanged = 'UIdw',
kDHeightChanged = 'UIdh',
kDFontSizeChanged = 'UIfs', kDFontSizeChanged = 'UIfs',
kGhostReads = 'Dbgh' kGhostReads = 'Dbgh'
#endif #endif
@ -105,6 +102,7 @@ class DeveloperDialog : public Dialog
CheckboxWidget* myRandomizeCPUWidget[5]; CheckboxWidget* myRandomizeCPUWidget[5];
CheckboxWidget* myUndrivenPinsWidget; CheckboxWidget* myUndrivenPinsWidget;
CheckboxWidget* myThumbExceptionWidget; CheckboxWidget* myThumbExceptionWidget;
CheckboxWidget* myEEPROMAccessWidget;
// Video widgets // Video widgets
RadioButtonGroup* mySettingsGroup1; RadioButtonGroup* mySettingsGroup1;
@ -120,18 +118,14 @@ class DeveloperDialog : public Dialog
RadioButtonGroup* mySettingsGroup2; RadioButtonGroup* mySettingsGroup2;
CheckboxWidget* myTimeMachineWidget; CheckboxWidget* myTimeMachineWidget;
SliderWidget* myStateSizeWidget; SliderWidget* myStateSizeWidget;
StaticTextWidget* myStateSizeLabelWidget;
SliderWidget* myUncompressedWidget; SliderWidget* myUncompressedWidget;
StaticTextWidget* myUncompressedLabelWidget;
PopUpWidget* myStateIntervalWidget; PopUpWidget* myStateIntervalWidget;
PopUpWidget* myStateHorizonWidget; PopUpWidget* myStateHorizonWidget;
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
// Debugger UI widgets // Debugger UI widgets
SliderWidget* myDebuggerWidthSlider; SliderWidget* myDebuggerWidthSlider;
StaticTextWidget* myDebuggerWidthLabel;
SliderWidget* myDebuggerHeightSlider; SliderWidget* myDebuggerHeightSlider;
StaticTextWidget* myDebuggerHeightLabel;
PopUpWidget* myDebuggerFontSize; PopUpWidget* myDebuggerFontSize;
PopUpWidget* myDebuggerFontStyle; PopUpWidget* myDebuggerFontStyle;
CheckboxWidget* myGhostReadsTrapWidget; CheckboxWidget* myGhostReadsTrapWidget;
@ -150,6 +144,7 @@ class DeveloperDialog : public Dialog
bool myDebugColors[2]; bool myDebugColors[2];
bool myUndrivenPins[2]; bool myUndrivenPins[2];
bool myThumbException[2]; bool myThumbException[2];
bool myEEPROMAccess[2];
// States sets // States sets
bool myTimeMachine[2]; bool myTimeMachine[2];
int myStateSize[2]; int myStateSize[2];
@ -162,8 +157,6 @@ class DeveloperDialog : public Dialog
void addTimeMachineTab(const GUI::Font& font); void addTimeMachineTab(const GUI::Font& font);
void addVideoTab(const GUI::Font& font); void addVideoTab(const GUI::Font& font);
void addDebuggerTab(const GUI::Font& font); void addDebuggerTab(const GUI::Font& font);
// Add Defaults, OK and Cancel buttons
void addDefaultOKCancelButtons(const GUI::Font& font);
void loadSettings(SettingsSet set); void loadSettings(SettingsSet set);
void saveSettings(SettingsSet set); void saveSettings(SettingsSet set);

View File

@ -27,6 +27,10 @@
#include "Dialog.hxx" #include "Dialog.hxx"
#include "Widget.hxx" #include "Widget.hxx"
#include "TabWidget.hxx" #include "TabWidget.hxx"
#include "ContextMenu.hxx"
#include "PopUpWidget.hxx"
#include "Vec.hxx" #include "Vec.hxx"
/* /*
@ -38,9 +42,34 @@
* ... * ...
*/ */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font, const string& title,
int x, int y, int w, int h)
: GuiObject(instance, parent, *this, x, y, w, h),
_font(&font),
_title(title),
_th(0),
_mouseWidget(nullptr),
_focusedWidget(nullptr),
_dragWidget(nullptr),
_okWidget(nullptr),
_cancelWidget(nullptr),
_visible(false),
_processCancel(false),
_surface(nullptr),
_tabID(0),
_flags(WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG)
{
initTitle(font, title);
}
Dialog::Dialog(OSystem& instance, DialogContainer& parent, Dialog::Dialog(OSystem& instance, DialogContainer& parent,
int x, int y, int w, int h) int x, int y, int w, int h)
: GuiObject(instance, parent, *this, x, y, w, h), : GuiObject(instance, parent, *this, x, y, w, h),
_font(nullptr),
_title(""),
_th(0),
_fh(0),
_mouseWidget(nullptr), _mouseWidget(nullptr),
_focusedWidget(nullptr), _focusedWidget(nullptr),
_dragWidget(nullptr), _dragWidget(nullptr),
@ -102,6 +131,29 @@ void Dialog::close(bool refresh)
parent().removeDialog(); parent().removeDialog();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::initTitle(const GUI::Font& font, const string& title)
{
_font = &font;
_fh = font.getLineHeight();
setTitle(title);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::setTitle(const string& title)
{
if(_font != nullptr)
{
_title = title;
_h -= _th;
if(title.empty())
_th = 0;
else
_th = _fh + 4;
_h += _th;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::center() void Dialog::center()
{ {
@ -270,15 +322,26 @@ void Dialog::drawDialog()
if(_dirty) if(_dirty)
{ {
// dialog is still on top if e.g a ContextMenu is opened
bool onTop = parent().myDialogStack.top() == this
|| parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
&& !parent().myDialogStack.top()->hasTitle();
if(_flags & WIDGET_CLEARBG) if(_flags & WIDGET_CLEARBG)
{
// cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl;
s.fillRect(_x, _y, _w, _h, kDlgColor); s.fillRect(_x, _y + _th, _w, _h - _th, onTop ? kDlgColor : kBGColorLo);
if(_th)
{
s.fillRect(_x, _y, _w, _th, onTop ? kColorTitleBar : kColorTitleBarLo);
s.drawString(*_font, _title, _x + 10, _y + 2 + 1, _font->getStringWidth(_title),
onTop ? kColorTitleText : kColorTitleTextLo);
}
}
else
s.invalidate();
if(_flags & WIDGET_BORDER) if(_flags & WIDGET_BORDER)
#ifndef FLAT_UI s.frameRect(_x, _y, _w, _h, onTop ? kColor : kShadowColor);
s.box(_x, _y, _w, _h, kColor, kShadowColor);
#else
s.frameRect(_x, _y, _w, _h, kColor);
#endif // !FLAT_UI
// Make all child widget dirty // Make all child widget dirty
Widget* w = _firstWidget; Widget* w = _firstWidget;
@ -662,23 +725,28 @@ Widget* Dialog::findWidget(int x, int y) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font, void Dialog::addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font,
const string& okText, const string& cancelText, const string& okText, const string& cancelText,
bool focusOKButton) bool focusOKButton, int buttonWidth)
{ {
int buttonWidth = std::max(font.getStringWidth("Cancel"), const int HBORDER = 10;
const int VBORDER = 10;
const int BTN_BORDER = 20;
const int BUTTON_GAP = 8;
buttonWidth = std::max(buttonWidth,
std::max(font.getStringWidth("Defaults"),
std::max(font.getStringWidth(okText), std::max(font.getStringWidth(okText),
font.getStringWidth(okText))) + 15; font.getStringWidth(cancelText))) + BTN_BORDER);
int buttonHeight = font.getLineHeight() + 4; int buttonHeight = font.getLineHeight() + 4;
#ifndef BSPF_MAC_OSX #ifndef BSPF_MAC_OSX
addOKWidget(new ButtonWidget(this, font, _w - 2 * (buttonWidth + 7), addOKWidget(new ButtonWidget(this, font, _w - 2 * buttonWidth - HBORDER - BUTTON_GAP,
_h - buttonHeight - 10, buttonWidth, buttonHeight, okText, GuiObject::kOKCmd)); _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, okText, GuiObject::kOKCmd));
addCancelWidget(new ButtonWidget(this, font, _w - (buttonWidth + 10), addCancelWidget(new ButtonWidget(this, font, _w - (buttonWidth + HBORDER),
_h - buttonHeight - 10, buttonWidth, buttonHeight, cancelText, GuiObject::kCloseCmd)); _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, cancelText, GuiObject::kCloseCmd));
#else #else
addCancelWidget(new ButtonWidget(this, font, _w - 2 * (buttonWidth + 7), addCancelWidget(new ButtonWidget(this, font, _w - 2 * buttonWidth - HBORDER - BUTTON_GAP,
_h - buttonHeight - 10, buttonWidth, buttonHeight, cancelText, GuiObject::kCloseCmd)); _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, cancelText, GuiObject::kCloseCmd));
addOKWidget(new ButtonWidget(this, font, _w - (buttonWidth + 10), addOKWidget(new ButtonWidget(this, font, _w - (buttonWidth + HBORDER),
_h - buttonHeight - 10, buttonWidth, buttonHeight, okText, GuiObject::kOKCmd)); _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, okText, GuiObject::kOKCmd));
#endif #endif
// Note that 'focusOKButton' only takes effect when there are no other UI // Note that 'focusOKButton' only takes effect when there are no other UI
@ -697,6 +765,25 @@ void Dialog::addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font,
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::addDefaultsOKCancelBGroup(WidgetArray& wid, const GUI::Font& font,
const string& okText, const string& cancelText,
const string& defaultsText,
bool focusOKButton)
{
const int HBORDER = 10;
const int VBORDER = 10;
const int BTN_BORDER = 20;
int buttonWidth = font.getStringWidth(defaultsText) + BTN_BORDER;
int buttonHeight = font.getLineHeight() + 4;
addDefaultWidget(new ButtonWidget(this, font, HBORDER, _h - buttonHeight - VBORDER,
buttonWidth, buttonHeight, defaultsText, GuiObject::kDefaultsCmd));
wid.push_back(_defaultWidget);
addOKCancelBGroup(wid, font, okText, cancelText, focusOKButton, buttonWidth);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::TabFocus::appendFocusList(WidgetArray& list) void Dialog::TabFocus::appendFocusList(WidgetArray& list)
{ {

View File

@ -46,6 +46,8 @@ class Dialog : public GuiObject
public: public:
Dialog(OSystem& instance, DialogContainer& parent, Dialog(OSystem& instance, DialogContainer& parent,
int x = 0, int y = 0, int w = 0, int h = 0); int x = 0, int y = 0, int w = 0, int h = 0);
Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font, const string& title,
int x = 0, int y = 0, int w = 0, int h = 0);
virtual ~Dialog(); virtual ~Dialog();
@ -65,6 +67,7 @@ class Dialog : public GuiObject
void addToFocusList(WidgetArray& list, TabWidget* w, int tabId); void addToFocusList(WidgetArray& list, TabWidget* w, int tabId);
void addBGroupToFocusList(WidgetArray& list) { _buttonGroup = list; } void addBGroupToFocusList(WidgetArray& list) { _buttonGroup = list; }
void addTabWidget(TabWidget* w); void addTabWidget(TabWidget* w);
void addDefaultWidget(Widget* w) { _defaultWidget = w; }
void addOKWidget(Widget* w) { _okWidget = w; } void addOKWidget(Widget* w) { _okWidget = w; }
void addCancelWidget(Widget* w) { _cancelWidget = w; } void addCancelWidget(Widget* w) { _cancelWidget = w; }
void setFocus(Widget* w); void setFocus(Widget* w);
@ -83,6 +86,9 @@ class Dialog : public GuiObject
void clearFlags(int flags) { _flags &= ~flags; setDirty(); } void clearFlags(int flags) { _flags &= ~flags; setDirty(); }
int getFlags() const { return _flags; } int getFlags() const { return _flags; }
void setTitle(const string& title);
bool hasTitle() { return !_title.empty(); }
protected: protected:
virtual void draw() override { } virtual void draw() override { }
void releaseFocus() override; void releaseFocus() override;
@ -106,6 +112,13 @@ class Dialog : public GuiObject
void addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font, void addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font,
const string& okText = "OK", const string& okText = "OK",
const string& cancelText = "Cancel", const string& cancelText = "Cancel",
bool focusOKButton = true,
int buttonWidth = 0);
void addDefaultsOKCancelBGroup(WidgetArray& wid, const GUI::Font& font,
const string& okText = "OK",
const string& cancelText = "Cancel",
const string& defaultsText = "Defaults",
bool focusOKButton = true); bool focusOKButton = true);
void processCancelWithoutWidget(bool state) { _processCancel = state; } void processCancelWithoutWidget(bool state) { _processCancel = state; }
@ -115,6 +128,8 @@ class Dialog : public GuiObject
*/ */
bool getResizableBounds(uInt32& w, uInt32& h) const; bool getResizableBounds(uInt32& w, uInt32& h) const;
void initTitle(const GUI::Font& font, const string& title);
private: private:
void buildCurrentFocusList(int tabID = -1); void buildCurrentFocusList(int tabID = -1);
bool handleNavEvent(Event::Type e); bool handleNavEvent(Event::Type e);
@ -125,10 +140,15 @@ class Dialog : public GuiObject
Widget* _mouseWidget; Widget* _mouseWidget;
Widget* _focusedWidget; Widget* _focusedWidget;
Widget* _dragWidget; Widget* _dragWidget;
Widget* _defaultWidget;
Widget* _okWidget; Widget* _okWidget;
Widget* _cancelWidget; Widget* _cancelWidget;
bool _visible; bool _visible;
bool _processCancel; bool _processCancel;
string _title;
int _th;
const GUI::Font* _font;
int _fh;
Common::FixedStack<shared_ptr<FBSurface>> mySurfaceStack; Common::FixedStack<shared_ptr<FBSurface>> mySurfaceStack;

View File

@ -40,6 +40,20 @@ void EditTextWidget::setText(const string& str, bool changed)
_changed = changed; _changed = changed;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EditTextWidget::handleMouseEntered()
{
setFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EditTextWidget::handleMouseLeft()
{
clearFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
{ {
@ -71,21 +85,10 @@ void EditTextWidget::drawWidget(bool hilite)
if(_changed) if(_changed)
s.fillRect(_x, _y, _w, _h, kDbgChangedColor); s.fillRect(_x, _y, _w, _h, kDbgChangedColor);
else if(!isEditable()) else if(!isEditable())
#ifndef FLAT_UI
s.fillRect(_x, _y, _w, _h, kBGColorHi);
#else
s.fillRect(_x, _y, _w, _h, kDlgColor); s.fillRect(_x, _y, _w, _h, kDlgColor);
#endif
// Draw a thin frame around us. // Draw a thin frame around us.
#ifndef FLAT_UI s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor);
s.hLine(_x, _y, _x + _w - 1, kColor);
s.hLine(_x, _y + _h - 1, _x +_w - 1, kShadowColor);
s.vLine(_x, _y, _y + _h - 1, kColor);
s.vLine(_x + _w - 1, _y, _y + _h - 1, kShadowColor);
#else
s.frameRect(_x, _y, _w, _h, kColor);
#endif
// Draw the text // Draw the text
adjustOffset(); adjustOffset();

View File

@ -43,6 +43,8 @@ class EditTextWidget : public EditableWidget
GUI::Rect getEditRect() const override; GUI::Rect getEditRect() const override;
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
void handleMouseEntered() override;
void handleMouseLeft() override;
protected: protected:
string _backupString; string _backupString;

View File

@ -50,17 +50,19 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
lineHeight = font.getLineHeight(), lineHeight = font.getLineHeight(),
buttonWidth = font.getStringWidth("Defaults") + 10, buttonWidth = font.getStringWidth("Defaults") + 10,
buttonHeight = font.getLineHeight() + 4; buttonHeight = font.getLineHeight() + 4;
int xpos = 5, ypos = 5; const int HBORDER = 8;
const int VBORDER = 8;
int xpos = HBORDER, ypos = VBORDER;
myActionsList = new StringListWidget(boss, font, xpos, ypos, myActionsList = new StringListWidget(boss, font, xpos, ypos,
_w - buttonWidth - 20, _h - 3*lineHeight); _w - buttonWidth - HBORDER * 2 - 8, _h - 3*lineHeight - VBORDER);
myActionsList->setTarget(this); myActionsList->setTarget(this);
myActionsList->setEditable(false); myActionsList->setEditable(false);
myActionsList->setList(actions); myActionsList->setList(actions);
addFocusWidget(myActionsList); addFocusWidget(myActionsList);
// Add remap, erase, cancel and default buttons // Add remap, erase, cancel and default buttons
xpos += myActionsList->getWidth() + 5; ypos += 5; xpos = _w - HBORDER - buttonWidth;
myMapButton = new ButtonWidget(boss, font, xpos, ypos, myMapButton = new ButtonWidget(boss, font, xpos, ypos,
buttonWidth, buttonHeight, buttonWidth, buttonHeight,
"Map" + ELLIPSIS, kStartMapCmd); "Map" + ELLIPSIS, kStartMapCmd);
@ -105,13 +107,13 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
myComboButton = nullptr; myComboButton = nullptr;
// Show message for currently selected event // Show message for currently selected event
xpos = 10; ypos = 5 + myActionsList->getHeight() + 5; xpos = HBORDER; ypos = VBORDER + myActionsList->getHeight() + 8;
StaticTextWidget* t; StaticTextWidget* t;
t = new StaticTextWidget(boss, font, xpos, ypos+2, font.getStringWidth("Action"), t = new StaticTextWidget(boss, font, xpos, ypos+2, font.getStringWidth("Action"),
fontHeight, "Action", TextAlign::Left); fontHeight, "Action", TextAlign::Left);
myKeyMapping = new EditTextWidget(boss, font, xpos + t->getWidth() + 8, ypos, myKeyMapping = new EditTextWidget(boss, font, xpos + t->getWidth() + 8, ypos,
_w - xpos - t->getWidth() - 15, lineHeight, ""); _w - xpos - t->getWidth() - 8 - HBORDER, lineHeight, "");
myKeyMapping->setEditable(false, true); myKeyMapping->setEditable(false, true);
myKeyMapping->clearFlags(WIDGET_RETAIN_FOCUS); myKeyMapping->clearFlags(WIDGET_RETAIN_FOCUS);
} }

View File

@ -21,6 +21,7 @@
#include "SaveKey.hxx" #include "SaveKey.hxx"
#include "Dialog.hxx" #include "Dialog.hxx"
#include "EditTextWidget.hxx" #include "EditTextWidget.hxx"
#include "RadioButtonWidget.hxx"
#include "Launcher.hxx" #include "Launcher.hxx"
#include "OSystem.hxx" #include "OSystem.hxx"
#include "PopUpWidget.hxx" #include "PopUpWidget.hxx"
@ -37,7 +38,7 @@
GameInfoDialog::GameInfoDialog( GameInfoDialog::GameInfoDialog(
OSystem& osystem, DialogContainer& parent, const GUI::Font& font, OSystem& osystem, DialogContainer& parent, const GUI::Font& font,
GuiObject* boss) GuiObject* boss)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "Game properties"),
CommandSender(boss), CommandSender(boss),
myPropertiesLoaded(false), myPropertiesLoaded(false),
myDefaultsSelected(false) myDefaultsSelected(false)
@ -48,146 +49,136 @@ GameInfoDialog::GameInfoDialog(
fontHeight = font.getFontHeight(), fontHeight = font.getFontHeight(),
buttonWidth = font.getStringWidth("Defaults") + 20, buttonWidth = font.getStringWidth("Defaults") + 20,
buttonHeight = font.getLineHeight() + 4; buttonHeight = font.getLineHeight() + 4;
const int vBorder = 4; const int vBorder = 8;
const int hBorder = 2; const int hBorder = 8;
const int hSpace = 10; const int hSpace = 10;
const int vGap = 4; const int VGAP = 4;
int xpos, ypos, lwidth, fwidth, pwidth, tabID; int xpos, ypos, lwidth, fwidth, pwidth, swidth, tabID;
WidgetArray wid; WidgetArray wid;
VariantList items, ports, ctrls; VariantList items, ports, ctrls;
StaticTextWidget* t; StaticTextWidget* t;
// Set real dimensions // Set real dimensions
_w = 52 * fontWidth + 8; _w = 53 * fontWidth + 8;
_h = 9 * (lineHeight + vGap) + vBorder * 2 + buttonHeight + fontHeight + ifont.getLineHeight() + 20; _h = 9 * (lineHeight + VGAP) + vBorder * 2 + _th + buttonHeight + fontHeight + ifont.getLineHeight() + 20;
// The tab widget // The tab widget
xpos = hBorder; ypos = vBorder; xpos = hBorder; ypos = vBorder;
myTab = new TabWidget(this, font, xpos, ypos, _w - 2 * hBorder, myTab = new TabWidget(this, font, 2, 4 + _th, _w - 2 * 2,
_h - (buttonHeight + fontHeight + ifont.getLineHeight() + 20)); _h - (_th + buttonHeight + fontHeight + ifont.getLineHeight() + 20));
addTabWidget(myTab); addTabWidget(myTab);
//////////////////////////////////////////////////////////////////////////////
// 1) Cartridge properties // 1) Cartridge properties
tabID = myTab->addTab("Cartridge"); tabID = myTab->addTab("Cartridge");
xpos = hSpace; xpos = hSpace;
lwidth = font.getStringWidth("Manufacturer "); lwidth = font.getStringWidth("Manufacturer ");
fwidth = _w - xpos - lwidth - hSpace - hBorder * 2; fwidth = _w - xpos - lwidth - hSpace - hBorder * 2;
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, "Name");
"Name", TextAlign::Left);
myName = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1, myName = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1,
fwidth, lineHeight, ""); fwidth, lineHeight, "");
wid.push_back(myName); wid.push_back(myName);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, "MD5");
"MD5", TextAlign::Left);
myMD5 = new EditTextWidget(myTab, font, xpos + lwidth, ypos-1, myMD5 = new EditTextWidget(myTab, font, xpos + lwidth, ypos-1,
fwidth, lineHeight, ""); fwidth, lineHeight, "");
myMD5->setEditable(false); myMD5->setEditable(false);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, "Manufacturer");
"Manufacturer", TextAlign::Left);
myManufacturer = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1, myManufacturer = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1,
fwidth, lineHeight, ""); fwidth, lineHeight, "");
wid.push_back(myManufacturer); wid.push_back(myManufacturer);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight,
"Model", TextAlign::Left); "Model", TextAlign::Left);
myModelNo = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1, myModelNo = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1,
fwidth, lineHeight, ""); fwidth, lineHeight, "");
wid.push_back(myModelNo); wid.push_back(myModelNo);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, "Rarity");
"Rarity", TextAlign::Left);
myRarity = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1, myRarity = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1,
fwidth, lineHeight, ""); fwidth, lineHeight, "");
wid.push_back(myRarity); wid.push_back(myRarity);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, "Note");
"Note", TextAlign::Left);
myNote = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1, myNote = new EditTextWidget(myTab, font, xpos+lwidth, ypos-1,
fwidth, lineHeight, ""); fwidth, lineHeight, "");
wid.push_back(myNote); wid.push_back(myNote);
ypos += lineHeight + VGAP;
ypos += lineHeight + vGap; new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, "Type");
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight,
"Sound", TextAlign::Left);
pwidth = font.getStringWidth("Stereo");
items.clear();
VarList::push_back(items, "Mono", "MONO");
VarList::push_back(items, "Stereo", "STEREO");
mySound = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
pwidth, lineHeight, items, "", 0, 0);
wid.push_back(mySound);
ypos += lineHeight + vGap;
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight,
"Type", TextAlign::Left);
pwidth = font.getStringWidth("CM (SpectraVideo CompuMate)"); pwidth = font.getStringWidth("CM (SpectraVideo CompuMate)");
items.clear(); items.clear();
for(int i = 0; i < int(BSType::NumSchemes); ++i) for(int i = 0; i < int(BSType::NumSchemes); ++i)
VarList::push_back(items, BSList[i].desc, BSList[i].name); VarList::push_back(items, BSList[i].desc, BSList[i].name);
myType = new PopUpWidget(myTab, font, xpos+lwidth, ypos, myType = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
pwidth, lineHeight, items, "", 0, 0); pwidth, lineHeight, items, "");
wid.push_back(myType); wid.push_back(myType);
ypos += lineHeight + VGAP;
mySound = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Stereo sound");
wid.push_back(mySound);
// Add items for tab 0 // Add items for tab 0
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
//////////////////////////////////////////////////////////////////////////////
// 2) Console properties // 2) Console properties
wid.clear(); wid.clear();
tabID = myTab->addTab("Console"); tabID = myTab->addTab("Console");
xpos = hSpace; ypos = vBorder; xpos = hSpace; ypos = vBorder;
lwidth = font.getStringWidth("Right Difficulty "); StaticTextWidget* s = new StaticTextWidget(myTab, font, xpos, ypos+1, "Left difficulty ");
pwidth = font.getStringWidth("B & W"); myLeftDiffGroup = new RadioButtonGroup();
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, RadioButtonWidget* r = new RadioButtonWidget(myTab, font, s->getRight(), ypos + 1,
"Left Difficulty", TextAlign::Left); "A", myLeftDiffGroup);
items.clear(); wid.push_back(r);
VarList::push_back(items, "B", "B"); ypos += lineHeight;
VarList::push_back(items, "A", "A"); r = new RadioButtonWidget(myTab, font, s->getRight(), ypos + 1,
myLeftDiff = new PopUpWidget(myTab, font, xpos+lwidth, ypos, "B", myLeftDiffGroup);
pwidth, lineHeight, items, "", 0, 0); wid.push_back(r);
wid.push_back(myLeftDiff); ypos += lineHeight + VGAP * 2;
ypos += lineHeight + vGap; s = new StaticTextWidget(myTab, font, xpos, ypos+1, "Right difficulty ");
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, myRightDiffGroup = new RadioButtonGroup();
"Right Difficulty", TextAlign::Left); r = new RadioButtonWidget(myTab, font, s->getRight(), ypos + 1,
// ... use same items as above "A", myRightDiffGroup);
myRightDiff = new PopUpWidget(myTab, font, xpos+lwidth, ypos, wid.push_back(r);
pwidth, lineHeight, items, "", 0, 0); ypos += lineHeight;
wid.push_back(myRightDiff); r = new RadioButtonWidget(myTab, font, s->getRight(), ypos + 1,
"B", myRightDiffGroup);
wid.push_back(r);
ypos += lineHeight + VGAP * 2;
ypos += lineHeight + vGap; s = new StaticTextWidget(myTab, font, xpos, ypos+1, "TV type ");
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, myTVTypeGroup = new RadioButtonGroup();
"TV Type", TextAlign::Left); r = new RadioButtonWidget(myTab, font, s->getRight(), ypos + 1,
items.clear(); "Color", myTVTypeGroup);
VarList::push_back(items, "Color", "COLOR"); wid.push_back(r);
VarList::push_back(items, "B & W", "BW"); ypos += lineHeight;
myTVType = new PopUpWidget(myTab, font, xpos+lwidth, ypos, r = new RadioButtonWidget(myTab, font, s->getRight(), ypos + 1,
pwidth, lineHeight, items, "", 0, 0); "B/W", myTVTypeGroup);
wid.push_back(myTVType); wid.push_back(r);
// Add items for tab 1 // Add items for tab 1
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
//////////////////////////////////////////////////////////////////////////////
// 3) Controller properties // 3) Controller properties
wid.clear(); wid.clear();
tabID = myTab->addTab("Controller"); tabID = myTab->addTab("Controller");
ypos = vBorder; ypos = vBorder;
pwidth = font.getStringWidth("Paddles_IAxis"); pwidth = font.getStringWidth("Paddles_IAxis");
myP0Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, myP0Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, "P0 controller ");
"P0 Controller ", TextAlign::Left);
ctrls.clear(); ctrls.clear();
VarList::push_back(ctrls, "Joystick", "JOYSTICK" ); VarList::push_back(ctrls, "Joystick", "JOYSTICK" );
VarList::push_back(ctrls, "Paddles", "PADDLES" ); VarList::push_back(ctrls, "Paddles", "PADDLES" );
@ -210,40 +201,34 @@ GameInfoDialog::GameInfoDialog(
pwidth, lineHeight, ctrls, "", 0, kLeftCChanged); pwidth, lineHeight, ctrls, "", 0, kLeftCChanged);
wid.push_back(myP0Controller); wid.push_back(myP0Controller);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
pwidth = font.getStringWidth("Paddles_IAxis"); pwidth = font.getStringWidth("Paddles_IAxis");
myP1Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, myP1Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, "P1 controller ");
"P1 Controller ", TextAlign::Left);
myP1Controller = new PopUpWidget(myTab, font, myP1Label->getRight(), myP1Label->getTop()-1, myP1Controller = new PopUpWidget(myTab, font, myP1Label->getRight(), myP1Label->getTop()-1,
pwidth, lineHeight, ctrls, "", 0, kRightCChanged); pwidth, lineHeight, ctrls, "", 0, kRightCChanged);
wid.push_back(myP1Controller); wid.push_back(myP1Controller);
//ypos += lineHeight + vGap; //ypos += lineHeight + VGAP;
mySwapPorts = new CheckboxWidget(myTab, font, myP0Controller->getRight() + fontWidth*5, myP0Controller->getTop()+1, mySwapPorts = new CheckboxWidget(myTab, font, myP0Controller->getRight() + fontWidth*4, myP0Controller->getTop()+1,
"Swap Ports"); "Swap ports");
wid.push_back(mySwapPorts); wid.push_back(mySwapPorts);
//ypos += lineHeight + vGap; //ypos += lineHeight + VGAP;
mySwapPaddles = new CheckboxWidget(myTab, font, myP1Controller->getRight() + fontWidth*5, myP1Controller->getTop()+1, mySwapPaddles = new CheckboxWidget(myTab, font, myP1Controller->getRight() + fontWidth*4, myP1Controller->getTop()+1,
"Swap Paddles"); "Swap paddles");
wid.push_back(mySwapPaddles); wid.push_back(mySwapPaddles);
// EEPROM erase button for P0 // EEPROM erase button for P0/P1
ypos += lineHeight + vGap + 4; ypos += lineHeight + VGAP + 4;
pwidth = myP1Controller->getWidth(); //font.getStringWidth("Erase EEPROM ") + 23;
myEraseEEPROMLabel = new StaticTextWidget(myTab, font, hSpace, ypos, "AtariVox/SaveKey "); myEraseEEPROMLabel = new StaticTextWidget(myTab, font, hSpace, ypos, "AtariVox/SaveKey ");
myEraseEEPROMButton = new ButtonWidget(myTab, font, myEraseEEPROMLabel->getRight(), ypos - 4, myEraseEEPROMButton = new ButtonWidget(myTab, font, myEraseEEPROMLabel->getRight(), ypos - 4,
"Erase EEPROM", kEEButtonPressed); pwidth, buttonHeight, "Erase EEPROM", kEEButtonPressed);
myEraseEEPROMInfo = new StaticTextWidget(myTab, ifont, myEraseEEPROMButton->getRight() + 4, myEraseEEPROMLabel->getTop() + 3, wid.push_back(myEraseEEPROMButton);
"(for this game only)"); myEraseEEPROMInfo = new StaticTextWidget(myTab, ifont, myEraseEEPROMButton->getRight() + 4,
myEraseEEPROMLabel->getTop() + 3, "(for this game only)");
ypos += lineHeight + vGap * 4; ypos += lineHeight + VGAP * 4;
lwidth = font.getStringWidth("Mouse axis mode "); myMouseControl = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Specific mouse axes", kMCtrlChanged);
pwidth = font.getStringWidth("Specific axis");
items.clear();
VarList::push_back(items, "Automatic", "AUTO");
VarList::push_back(items, "Specific axis", "specific");
myMouseControl =
new PopUpWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, items,
"Mouse axis mode ", lwidth, kMCtrlChanged);
wid.push_back(myMouseControl); wid.push_back(myMouseControl);
// Mouse controller specific axis // Mouse controller specific axis
@ -259,41 +244,36 @@ GameInfoDialog::GameInfoDialog(
VarList::push_back(items, "MindLink 0", MouseControl::MindLink0); VarList::push_back(items, "MindLink 0", MouseControl::MindLink0);
VarList::push_back(items, "MindLink 1", MouseControl::MindLink1); VarList::push_back(items, "MindLink 1", MouseControl::MindLink1);
xpos = hSpace + lwidth;
lwidth = font.getStringWidth("X-Axis is "); lwidth = font.getStringWidth("X-Axis is ");
xpos -= lwidth; xpos += 20;
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
myMouseX = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, myMouseX = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items,
"X-Axis is "); "X-Axis is ");
wid.push_back(myMouseX); wid.push_back(myMouseX);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
myMouseY = new PopUpWidget(myTab, font, myMouseX->getLeft(), ypos, pwidth, lineHeight, items, myMouseY = new PopUpWidget(myTab, font, myMouseX->getLeft(), ypos, pwidth, lineHeight, items,
"Y-Axis is "); "Y-Axis is ");
wid.push_back(myMouseY); wid.push_back(myMouseY);
xpos = hSpace; ypos += lineHeight + vGap; xpos = hSpace; ypos += lineHeight + VGAP;
lwidth = font.getStringWidth("Mouse axis range "); lwidth = font.getStringWidth("Mouse axis range ");
myMouseRange = new SliderWidget(myTab, font, hSpace, ypos, 8*fontWidth, lineHeight, myMouseRange = new SliderWidget(myTab, font, hSpace, ypos,
"Mouse axis range ", lwidth, kMRangeChanged); "Mouse axis range ", lwidth, 0, fontWidth * 4, "%");
myMouseRange->setMinValue(1); myMouseRange->setMaxValue(100); myMouseRange->setMinValue(1); myMouseRange->setMaxValue(100);
wid.push_back(myMouseRange); wid.push_back(myMouseRange);
myMouseRangeLabel = new StaticTextWidget(myTab, font,
myMouseRange->getRight() + 4, myMouseRange->getTop()+1,
" ", TextAlign::Left);
// Add items for tab 2 // Add items for tab 2
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
//////////////////////////////////////////////////////////////////////////////
// 4) Display properties // 4) Display properties
wid.clear(); wid.clear();
tabID = myTab->addTab("Display"); tabID = myTab->addTab("Display");
ypos = vBorder; ypos = vBorder;
pwidth = font.getStringWidth("Auto-detect"); pwidth = font.getStringWidth("Auto-detect");
t = new StaticTextWidget(myTab, font, hSpace, ypos+1, "Format ", TextAlign::Left); t = new StaticTextWidget(myTab, font, hSpace, ypos+1, "Format ");
items.clear(); items.clear();
VarList::push_back(items, "Auto-detect", "AUTO"); VarList::push_back(items, "Auto-detect", "AUTO");
VarList::push_back(items, "NTSC", "NTSC"); VarList::push_back(items, "NTSC", "NTSC");
@ -306,43 +286,34 @@ GameInfoDialog::GameInfoDialog(
pwidth, lineHeight, items, "", 0, 0); pwidth, lineHeight, items, "", 0, 0);
wid.push_back(myFormat); wid.push_back(myFormat);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
t = new StaticTextWidget(myTab, font, hSpace, ypos+1, "YStart ", TextAlign::Left); swidth = myFormat->getWidth();
myYStart = new SliderWidget(myTab, font, t->getRight(), ypos, 8*fontWidth, lineHeight, t = new StaticTextWidget(myTab, font, hSpace, ypos+1, "Y-Start ");
"", 0, kYStartChanged); myYStart = new SliderWidget(myTab, font, t->getRight(), ypos, swidth, lineHeight,
"", 0, kYStartChanged, 4 * fontWidth, "px");
myYStart->setMinValue(TIAConstants::minYStart-1); myYStart->setMinValue(TIAConstants::minYStart-1);
myYStart->setMaxValue(TIAConstants::maxYStart); myYStart->setMaxValue(TIAConstants::maxYStart);
wid.push_back(myYStart); wid.push_back(myYStart);
myYStartLabel = new StaticTextWidget(myTab, font, myYStart->getRight() + 4,
ypos+1, 5*fontWidth, fontHeight, "", TextAlign::Left);
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
t = new StaticTextWidget(myTab, font, hSpace, ypos+1, "Height ", TextAlign::Left); t = new StaticTextWidget(myTab, font, hSpace, ypos+1, "Height ");
myHeight = new SliderWidget(myTab, font, t->getRight(), ypos, 8*fontWidth, lineHeight, myHeight = new SliderWidget(myTab, font, t->getRight(), ypos, swidth, lineHeight,
"", 0, kHeightChanged); "", 0, kHeightChanged, 5 * fontWidth, "px");
myHeight->setMinValue(TIAConstants::minViewableHeight-1); myHeight->setMinValue(TIAConstants::minViewableHeight-1);
myHeight->setMaxValue(TIAConstants::maxViewableHeight); myHeight->setMaxValue(TIAConstants::maxViewableHeight);
wid.push_back(myHeight); wid.push_back(myHeight);
myHeightLabel = new StaticTextWidget(myTab, font, myHeight->getRight() + 4,
ypos+1, 5*fontWidth, fontHeight, "", TextAlign::Left);
// Phosphor // Phosphor
ypos += lineHeight + vGap*4; ypos += lineHeight + VGAP*4;
myPhosphor = new CheckboxWidget(myTab, font, hSpace, ypos+1, "Use Phosphor", kPhosphorChanged); myPhosphor = new CheckboxWidget(myTab, font, hSpace, ypos+1, "Phosphor", kPhosphorChanged);
wid.push_back(myPhosphor); wid.push_back(myPhosphor);
myPPBlend = new SliderWidget(myTab, font, myPPBlend = new SliderWidget(myTab, font,
myPhosphor->getRight() + 16, myPhosphor->getTop()-2, myPhosphor->getRight() + fontWidth * 3, myPhosphor->getTop()-2,
8*fontWidth, lineHeight, "Blend ", "Blend ", 0, kPPBlendChanged, 7 * fontWidth, "%");
font.getStringWidth("Blend "),
kPPBlendChanged);
myPPBlend->setMinValue(0); myPPBlend->setMaxValue(100); myPPBlend->setMinValue(0); myPPBlend->setMaxValue(100);
wid.push_back(myPPBlend); wid.push_back(myPPBlend);
myPPBlendLabel = new StaticTextWidget(myTab, font,
myPPBlend->getRight() + 4, myPhosphor->getTop(),
5*fontWidth, fontHeight, "", TextAlign::Left);
// Add items for tab 3 // Add items for tab 3
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
@ -353,17 +324,11 @@ GameInfoDialog::GameInfoDialog(
// Add message concerning usage // Add message concerning usage
lwidth = ifont.getStringWidth("(*) Changes to properties require a ROM reload"); lwidth = ifont.getStringWidth("(*) Changes to properties require a ROM reload");
new StaticTextWidget(this, ifont, hSpace, _h - (buttonHeight + fontHeight + 20), new StaticTextWidget(this, ifont, hSpace, _h - (buttonHeight + fontHeight + 20),
lwidth, fontHeight, "(*) Changes to properties require a ROM reload");
"(*) Changes to properties require a ROM reload",
TextAlign::Left);
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
wid.clear(); wid.clear();
ButtonWidget* b; addDefaultsOKCancelBGroup(wid, font);
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font);
addBGroupToFocusList(wid); addBGroupToFocusList(wid);
} }
@ -406,13 +371,13 @@ void GameInfoDialog::loadView()
myModelNo->setText(myGameProperties.get(Cartridge_ModelNo)); myModelNo->setText(myGameProperties.get(Cartridge_ModelNo));
myRarity->setText(myGameProperties.get(Cartridge_Rarity)); myRarity->setText(myGameProperties.get(Cartridge_Rarity));
myNote->setText(myGameProperties.get(Cartridge_Note)); myNote->setText(myGameProperties.get(Cartridge_Note));
mySound->setSelected(myGameProperties.get(Cartridge_Sound), "MONO"); mySound->setState(myGameProperties.get(Cartridge_Sound) == "STEREO");
myType->setSelected(myGameProperties.get(Cartridge_Type), "AUTO"); myType->setSelected(myGameProperties.get(Cartridge_Type), "AUTO");
// Console properties // Console properties
myLeftDiff->setSelected(myGameProperties.get(Console_LeftDifficulty), "B"); myLeftDiffGroup->setSelected(myGameProperties.get(Console_LeftDifficulty) == "A" ? 0 : 1);
myRightDiff->setSelected(myGameProperties.get(Console_RightDifficulty), "B"); myRightDiffGroup->setSelected(myGameProperties.get(Console_RightDifficulty) == "A" ? 0 : 1);
myTVType->setSelected(myGameProperties.get(Console_TelevisionType), "COLOR"); myTVTypeGroup->setSelected(myGameProperties.get(Console_TelevisionType) == "BW" ? 1 : 0);
// Controller properties // Controller properties
myP0Controller->setSelected(myGameProperties.get(Controller_Left), "JOYSTICK"); myP0Controller->setSelected(myGameProperties.get(Controller_Left), "JOYSTICK");
@ -425,15 +390,16 @@ void GameInfoDialog::loadView()
string m_control, m_range; string m_control, m_range;
m_axis >> m_control; m_axis >> m_control;
bool autoAxis = BSPF::equalsIgnoreCase(m_control, "AUTO"); bool autoAxis = BSPF::equalsIgnoreCase(m_control, "AUTO");
myMouseControl->setState(!autoAxis);
if(autoAxis) if(autoAxis)
{ {
myMouseControl->setSelectedIndex(0); //myMouseControl->setSelectedIndex(0);
myMouseX->setSelectedIndex(0); myMouseX->setSelectedIndex(0);
myMouseY->setSelectedIndex(0); myMouseY->setSelectedIndex(0);
} }
else else
{ {
myMouseControl->setSelectedIndex(1); //myMouseControl->setSelectedIndex(1);
myMouseX->setSelected(m_control[0] - '0'); myMouseX->setSelected(m_control[0] - '0');
myMouseY->setSelected(m_control[1] - '0'); myMouseY->setSelected(m_control[1] - '0');
} }
@ -442,12 +408,10 @@ void GameInfoDialog::loadView()
if(m_axis >> m_range) if(m_axis >> m_range)
{ {
myMouseRange->setValue(atoi(m_range.c_str())); myMouseRange->setValue(atoi(m_range.c_str()));
myMouseRangeLabel->setLabel(m_range);
} }
else else
{ {
myMouseRange->setValue(100); myMouseRange->setValue(100);
myMouseRangeLabel->setLabel("100");
} }
// Display properties // Display properties
@ -455,20 +419,22 @@ void GameInfoDialog::loadView()
const string& ystart = myGameProperties.get(Display_YStart); const string& ystart = myGameProperties.get(Display_YStart);
myYStart->setValue(atoi(ystart.c_str())); myYStart->setValue(atoi(ystart.c_str()));
myYStartLabel->setLabel(ystart == "0" ? "Auto" : ystart); myYStart->setValueLabel(ystart == "0" ? "Auto" : ystart);
myYStart->setValueUnit(ystart == "0" ? "" : "px");
const string& height = myGameProperties.get(Display_Height); const string& height = myGameProperties.get(Display_Height);
myHeight->setValue(atoi(height.c_str())); myHeight->setValue(atoi(height.c_str()));
myHeightLabel->setLabel(height == "0" ? "Auto" : height); myHeight->setValueLabel(height == "0" ? "Auto" : height);
myHeight->setValueUnit(height == "0" ? "" : "px");
bool usePhosphor = myGameProperties.get(Display_Phosphor) == "YES"; bool usePhosphor = myGameProperties.get(Display_Phosphor) == "YES";
myPhosphor->setState(usePhosphor); myPhosphor->setState(usePhosphor);
myPPBlend->setEnabled(usePhosphor); myPPBlend->setEnabled(usePhosphor);
myPPBlendLabel->setEnabled(usePhosphor);
const string& blend = myGameProperties.get(Display_PPBlend); const string& blend = myGameProperties.get(Display_PPBlend);
myPPBlend->setValue(atoi(blend.c_str())); myPPBlend->setValue(atoi(blend.c_str()));
myPPBlendLabel->setLabel(blend == "0" ? "Auto" : blend); myPPBlend->setValueLabel(blend == "0" ? "Default" : blend);
myPPBlend->setValueUnit(blend == "0" ? "" : "%");
myTab->loadConfig(); myTab->loadConfig();
} }
@ -485,13 +451,13 @@ void GameInfoDialog::saveConfig()
myGameProperties.set(Cartridge_ModelNo, myModelNo->getText()); myGameProperties.set(Cartridge_ModelNo, myModelNo->getText());
myGameProperties.set(Cartridge_Rarity, myRarity->getText()); myGameProperties.set(Cartridge_Rarity, myRarity->getText());
myGameProperties.set(Cartridge_Note, myNote->getText()); myGameProperties.set(Cartridge_Note, myNote->getText());
myGameProperties.set(Cartridge_Sound, mySound->getSelectedTag().toString()); myGameProperties.set(Cartridge_Sound, mySound->getState() ? "STEREO" : "MONO");
myGameProperties.set(Cartridge_Type, myType->getSelectedTag().toString()); myGameProperties.set(Cartridge_Type, myType->getSelectedTag().toString());
// Console properties // Console properties
myGameProperties.set(Console_LeftDifficulty, myLeftDiff->getSelectedTag().toString()); myGameProperties.set(Console_LeftDifficulty, myLeftDiffGroup->getSelected() ? "B" : "A");
myGameProperties.set(Console_RightDifficulty, myRightDiff->getSelectedTag().toString()); myGameProperties.set(Console_RightDifficulty, myRightDiffGroup->getSelected() ? "B" : "A");
myGameProperties.set(Console_TelevisionType, myTVType->getSelectedTag().toString()); myGameProperties.set(Console_TelevisionType, myTVTypeGroup->getSelected() ? "BW" : "COLOR");
// Controller properties // Controller properties
myGameProperties.set(Controller_Left, myP0Controller->getSelectedTag().toString()); myGameProperties.set(Controller_Left, myP0Controller->getSelectedTag().toString());
@ -500,25 +466,25 @@ void GameInfoDialog::saveConfig()
myGameProperties.set(Controller_SwapPaddles, (mySwapPaddles->isEnabled() && mySwapPaddles->getState()) ? "YES" : "NO"); myGameProperties.set(Controller_SwapPaddles, (mySwapPaddles->isEnabled() && mySwapPaddles->getState()) ? "YES" : "NO");
// MouseAxis property (potentially contains 'range' information) // MouseAxis property (potentially contains 'range' information)
string mcontrol = myMouseControl->getSelectedTag().toString(); string mcontrol = "AUTO";
if(mcontrol != "AUTO") if(myMouseControl->getState())
mcontrol = myMouseX->getSelectedTag().toString() + mcontrol = myMouseX->getSelectedTag().toString() +
myMouseY->getSelectedTag().toString(); myMouseY->getSelectedTag().toString();
string range = myMouseRangeLabel->getLabel(); string range = myMouseRange->getValueLabel();
if(range != "100") if(range != "100")
mcontrol += " " + range; mcontrol += " " + range;
myGameProperties.set(Controller_MouseAxis, mcontrol); myGameProperties.set(Controller_MouseAxis, mcontrol);
// Display properties // Display properties
myGameProperties.set(Display_Format, myFormat->getSelectedTag().toString()); myGameProperties.set(Display_Format, myFormat->getSelectedTag().toString());
myGameProperties.set(Display_YStart, myYStartLabel->getLabel() == "Auto" ? "0" : myGameProperties.set(Display_YStart, myYStart->getValueLabel() == "Auto" ? "0" :
myYStartLabel->getLabel()); myYStart->getValueLabel());
myGameProperties.set(Display_Height, myHeightLabel->getLabel() == "Auto" ? "0" : myGameProperties.set(Display_Height, myHeight->getValueLabel() == "Auto" ? "0" :
myHeightLabel->getLabel()); myHeight->getValueLabel());
myGameProperties.set(Display_Phosphor, myPhosphor->getState() ? "YES" : "NO"); myGameProperties.set(Display_Phosphor, myPhosphor->getState() ? "YES" : "NO");
myGameProperties.set(Display_PPBlend, myPPBlendLabel->getLabel() == "Auto" ? "0" : myGameProperties.set(Display_PPBlend, myPPBlend->getValueLabel() == "Default" ? "0" :
myPPBlendLabel->getLabel()); myPPBlend->getValueLabel());
// Determine whether to add or remove an entry from the properties set // Determine whether to add or remove an entry from the properties set
if(myDefaultsSelected) if(myDefaultsSelected)
@ -639,38 +605,44 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
{ {
bool status = myPhosphor->getState(); bool status = myPhosphor->getState();
myPPBlend->setEnabled(status); myPPBlend->setEnabled(status);
myPPBlendLabel->setEnabled(status);
break; break;
} }
case kYStartChanged: case kYStartChanged:
if(myYStart->getValue() == TIAConstants::minYStart-1) if(myYStart->getValue() == TIAConstants::minYStart-1)
myYStartLabel->setLabel("Auto"); {
myYStart->setValueLabel("Auto");
myYStart->setValueUnit("");
}
else else
myYStartLabel->setValue(myYStart->getValue()); myYStart->setValueUnit("px");
break; break;
case kHeightChanged: case kHeightChanged:
if(myHeight->getValue() == TIAConstants::minViewableHeight-1) if(myHeight->getValue() == TIAConstants::minViewableHeight-1)
myHeightLabel->setLabel("Auto"); {
myHeight->setValueLabel("Auto");
myHeight->setValueUnit("");
}
else else
myHeightLabel->setValue(myHeight->getValue()); myHeight->setValueUnit("px");
break; break;
case kPPBlendChanged: case kPPBlendChanged:
if(myPPBlend->getValue() == 0) if(myPPBlend->getValue() == 0)
myPPBlendLabel->setLabel("Auto"); {
myPPBlend->setValueLabel("Default");
myPPBlend->setValueUnit("");
}
else else
myPPBlendLabel->setValue(myPPBlend->getValue()); myPPBlend->setValueUnit("%");
break;
case kMRangeChanged:
myMouseRangeLabel->setValue(myMouseRange->getValue());
break; break;
case kMCtrlChanged: case kMCtrlChanged:
{ {
bool state = myMouseControl->getSelectedTag() != "AUTO"; //bool state = myMouseControl->getSelectedTag() != "AUTO";
bool state = myMouseControl->getState();
myMouseX->setEnabled(state); myMouseX->setEnabled(state);
myMouseY->setEnabled(state); myMouseY->setEnabled(state);
break; break;

View File

@ -23,6 +23,7 @@ class GuiObject;
class EditTextWidget; class EditTextWidget;
class PopUpWidget; class PopUpWidget;
class StaticTextWidget; class StaticTextWidget;
class RadioButtonGroup;
class TabWidget; class TabWidget;
class SliderWidget; class SliderWidget;
@ -58,13 +59,13 @@ class GameInfoDialog : public Dialog, public CommandSender
EditTextWidget* myModelNo; EditTextWidget* myModelNo;
EditTextWidget* myRarity; EditTextWidget* myRarity;
EditTextWidget* myNote; EditTextWidget* myNote;
PopUpWidget* mySound;
PopUpWidget* myType; PopUpWidget* myType;
CheckboxWidget* mySound;
// Console properties // Console properties
PopUpWidget* myLeftDiff; RadioButtonGroup* myLeftDiffGroup;
PopUpWidget* myRightDiff; RadioButtonGroup* myRightDiffGroup;
PopUpWidget* myTVType; RadioButtonGroup* myTVTypeGroup;
// Controller properties // Controller properties
StaticTextWidget* myP0Label; StaticTextWidget* myP0Label;
@ -76,26 +77,21 @@ class GameInfoDialog : public Dialog, public CommandSender
StaticTextWidget* myEraseEEPROMLabel; StaticTextWidget* myEraseEEPROMLabel;
ButtonWidget* myEraseEEPROMButton; ButtonWidget* myEraseEEPROMButton;
StaticTextWidget* myEraseEEPROMInfo; StaticTextWidget* myEraseEEPROMInfo;
PopUpWidget* myMouseControl; CheckboxWidget* myMouseControl;
PopUpWidget* myMouseX; PopUpWidget* myMouseX;
PopUpWidget* myMouseY; PopUpWidget* myMouseY;
SliderWidget* myMouseRange; SliderWidget* myMouseRange;
StaticTextWidget* myMouseRangeLabel;
// Display properties // Display properties
PopUpWidget* myFormat; PopUpWidget* myFormat;
SliderWidget* myYStart; SliderWidget* myYStart;
StaticTextWidget* myYStartLabel;
SliderWidget* myHeight; SliderWidget* myHeight;
StaticTextWidget* myHeightLabel;
CheckboxWidget* myPhosphor; CheckboxWidget* myPhosphor;
SliderWidget* myPPBlend; SliderWidget* myPPBlend;
StaticTextWidget* myPPBlendLabel;
enum { enum {
kLeftCChanged = 'LCch', kLeftCChanged = 'LCch',
kRightCChanged = 'RCch', kRightCChanged = 'RCch',
kMRangeChanged = 'MRch',
kYStartChanged = 'YSch', kYStartChanged = 'YSch',
kHeightChanged = 'HTch', kHeightChanged = 'HTch',
kPhosphorChanged = 'PPch', kPhosphorChanged = 'PPch',

View File

@ -30,7 +30,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font) GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font)
: Dialog(boss->instance(), boss->parent()), : Dialog(boss->instance(), boss->parent(), font, "Power-on options"),
CommandSender(boss) CommandSender(boss)
{ {
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
@ -47,9 +47,9 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font)
// Set real dimensions // Set real dimensions
_w = lwidth + pwidth + fontWidth*3 + 15; _w = lwidth + pwidth + fontWidth*3 + 15;
_h = 17 * (lineHeight + 4) + buttonHeight + 20; _h = 17 * (lineHeight + 4) + buttonHeight + 20 + _th;
xpos = 10; ypos = 10; xpos = 10; ypos = 10 + _th;
// Bankswitch type // Bankswitch type
new StaticTextWidget(this, font, xpos, ypos+1, lwidth, fontHeight, new StaticTextWidget(this, font, xpos, ypos+1, lwidth, fontHeight,
@ -133,11 +133,7 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font)
" further ROMs until clicking 'Defaults'", TextAlign::Left); " further ROMs until clicking 'Defaults'", TextAlign::Left);
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
ButtonWidget* b; addDefaultsOKCancelBGroup(wid, font, "Load ROM", "Close");
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font, "Load ROM", "Close");
addToFocusList(wid); addToFocusList(wid);
} }

View File

@ -24,7 +24,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HelpDialog::HelpDialog(OSystem& osystem, DialogContainer& parent, HelpDialog::HelpDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font) const GUI::Font& font)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "Help"),
myPage(1), myPage(1),
myNumPages(5) myNumPages(5)
{ {
@ -39,7 +39,7 @@ HelpDialog::HelpDialog(OSystem& osystem, DialogContainer& parent,
// Set real dimensions // Set real dimensions
_w = 46 * fontWidth + 10; _w = 46 * fontWidth + 10;
_h = 12 * lineHeight + 20; _h = 12 * lineHeight + 20 + _th;
// Add Previous, Next and Close buttons // Add Previous, Next and Close buttons
xpos = 10; ypos = _h - buttonHeight - 10; xpos = 10; ypos = _h - buttonHeight - 10;
@ -49,7 +49,7 @@ HelpDialog::HelpDialog(OSystem& osystem, DialogContainer& parent,
myPrevButton->clearFlags(WIDGET_ENABLED); myPrevButton->clearFlags(WIDGET_ENABLED);
wid.push_back(myPrevButton); wid.push_back(myPrevButton);
xpos += buttonWidth + 7; xpos += buttonWidth + 8;
myNextButton = myNextButton =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Next", GuiObject::kNextCmd); "Next", GuiObject::kNextCmd);
@ -60,9 +60,9 @@ HelpDialog::HelpDialog(OSystem& osystem, DialogContainer& parent,
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Close", GuiObject::kCloseCmd); "Close", GuiObject::kCloseCmd);
wid.push_back(b); wid.push_back(b);
addOKWidget(b); addCancelWidget(b); addCancelWidget(b);
xpos = 5; ypos = 5; xpos = 5; ypos = 5 + _th;
myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - 10, fontHeight, myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - 10, fontHeight,
"", TextAlign::Center); "", TextAlign::Center);

View File

@ -38,11 +38,10 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent, InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h) const GUI::Font& font, int max_w, int max_h)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "Input settings"),
myConfirmMsg(nullptr), myConfirmMsg(nullptr),
myMaxWidth(max_w), myMaxWidth(max_w),
myMaxHeight(max_h) myMaxHeight(max_h)
{ {
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth(), fontWidth = font.getMaxCharWidth(),
@ -54,11 +53,11 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
// Set real dimensions // Set real dimensions
_w = std::min(50 * fontWidth + 10, max_w); _w = std::min(50 * fontWidth + 10, max_w);
_h = std::min(16 * (lineHeight + 4) + 14, max_h); _h = std::min(16 * (lineHeight + 4) + 16 + _th, max_h);
// The tab widget // The tab widget
xpos = 2; ypos = vBorder; xpos = 2; ypos = vBorder + _th;
myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h - buttonHeight - 20); myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h -_th - buttonHeight - 20);
addTabWidget(myTab); addTabWidget(myTab);
// 1) Event mapper for emulation actions // 1) Event mapper for emulation actions
@ -66,7 +65,7 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
actions = instance().eventHandler().getActionList(kEmulationMode); actions = instance().eventHandler().getActionList(kEmulationMode);
myEmulEventMapper = new EventMappingWidget(myTab, font, 2, 2, myEmulEventMapper = new EventMappingWidget(myTab, font, 2, 2,
myTab->getWidth(), myTab->getWidth(),
myTab->getHeight() - ypos, myTab->getHeight() - 4,
actions, kEmulationMode); actions, kEmulationMode);
myTab->setParentWidget(tabID, myEmulEventMapper); myTab->setParentWidget(tabID, myEmulEventMapper);
addToFocusList(myEmulEventMapper->getFocusList(), myTab, tabID); addToFocusList(myEmulEventMapper->getFocusList(), myTab, tabID);
@ -76,7 +75,7 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
actions = instance().eventHandler().getActionList(kMenuMode); actions = instance().eventHandler().getActionList(kMenuMode);
myMenuEventMapper = new EventMappingWidget(myTab, font, 2, 2, myMenuEventMapper = new EventMappingWidget(myTab, font, 2, 2,
myTab->getWidth(), myTab->getWidth(),
myTab->getHeight() - ypos, myTab->getHeight() - 4,
actions, kMenuMode); actions, kMenuMode);
myTab->setParentWidget(tabID, myMenuEventMapper); myTab->setParentWidget(tabID, myMenuEventMapper);
addToFocusList(myMenuEventMapper->getFocusList(), myTab, tabID); addToFocusList(myMenuEventMapper->getFocusList(), myTab, tabID);
@ -90,11 +89,7 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
WidgetArray wid; WidgetArray wid;
ButtonWidget* b; addDefaultsOKCancelBGroup(wid, font);
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font);
addBGroupToFocusList(wid); addBGroupToFocusList(wid);
} }
@ -112,41 +107,34 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
int xpos, ypos, lwidth, pwidth, tabID; int xpos, ypos, lwidth, pwidth, tabID;
WidgetArray wid; WidgetArray wid;
VariantList items; VariantList items;
const int vGap = 4; const int VGAP = 4;
const int hSpace = 8; const int VBORDER = 9;
const int HBORDER = 8;
// Devices/ports // Devices/ports
tabID = myTab->addTab("Devices & Ports"); tabID = myTab->addTab("Devices & Ports");
// Stelladaptor mappings ypos = VBORDER;
ypos = vGap+2;
lwidth = font.getStringWidth("Digital paddle sensitivity "); // was: "Use mouse as a controller " lwidth = font.getStringWidth("Digital paddle sensitivity "); // was: "Use mouse as a controller "
pwidth = font.getStringWidth("-UI, -Emulation"); pwidth = font.getStringWidth("-UI, -Emulation");
VarList::push_back(items, "Left / Right", "lr");
VarList::push_back(items, "Right / Left", "rl");
mySAPort = new PopUpWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, items,
"Stelladaptor port order ", lwidth);
wid.push_back(mySAPort);
// Use mouse as controller // Use mouse as controller
ypos += lineHeight + vGap;
items.clear(); items.clear();
VarList::push_back(items, "Always", "always"); VarList::push_back(items, "Always", "always");
VarList::push_back(items, "Analog devices", "analog"); VarList::push_back(items, "Analog devices", "analog");
VarList::push_back(items, "Never", "never"); VarList::push_back(items, "Never", "never");
myMouseControl = new PopUpWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, items, myMouseControl = new PopUpWidget(myTab, font, HBORDER, ypos, pwidth, lineHeight, items,
"Use mouse as a controller ", lwidth); "Use mouse as a controller ", lwidth);
wid.push_back(myMouseControl); wid.push_back(myMouseControl);
// Mouse cursor state // Mouse cursor state
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
items.clear(); items.clear();
VarList::push_back(items, "-UI, -Emulation", "0"); VarList::push_back(items, "-UI, -Emulation", "0");
VarList::push_back(items, "-UI, +Emulation", "1"); VarList::push_back(items, "-UI, +Emulation", "1");
VarList::push_back(items, "+UI, -Emulation", "2"); VarList::push_back(items, "+UI, -Emulation", "2");
VarList::push_back(items, "+UI, +Emulation", "3"); VarList::push_back(items, "+UI, +Emulation", "3");
myCursorState = new PopUpWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, items, myCursorState = new PopUpWidget(myTab, font, HBORDER, ypos, pwidth, lineHeight, items,
"Mouse cursor visibility ", lwidth); "Mouse cursor visibility ", lwidth);
wid.push_back(myCursorState); wid.push_back(myCursorState);
#ifndef WINDOWED_SUPPORT #ifndef WINDOWED_SUPPORT
@ -157,57 +145,53 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
pwidth = font.getMaxCharWidth() * 8; pwidth = font.getMaxCharWidth() * 8;
// Add joystick deadzone setting // Add joystick deadzone setting
ypos += lineHeight + vGap*3; ypos += lineHeight + VGAP*3;
myDeadzone = new SliderWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, myDeadzone = new SliderWidget(myTab, font, HBORDER, ypos,
"Joystick deadzone size ", lwidth, kDeadzoneChanged); "Joystick deadzone size ", lwidth, kDeadzoneChanged);
myDeadzone->setMinValue(0); myDeadzone->setMaxValue(29); myDeadzone->setMinValue(0); myDeadzone->setMaxValue(29);
xpos = hSpace + myDeadzone->getWidth() + 5; xpos = HBORDER + myDeadzone->getWidth() + 5;
myDeadzoneLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 5*fontWidth, myDeadzoneLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 5*fontWidth, lineHeight, "");
lineHeight, "", TextAlign::Left);
wid.push_back(myDeadzone); wid.push_back(myDeadzone);
// Add paddle speed (digital emulation) // Add paddle speed (digital emulation)
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
myDPaddleSpeed = new SliderWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, myDPaddleSpeed = new SliderWidget(myTab, font, HBORDER, ypos,
"Digital paddle sensitivity ", "Digital paddle sensitivity ",
lwidth, kDPSpeedChanged); lwidth, kDPSpeedChanged);
myDPaddleSpeed->setMinValue(1); myDPaddleSpeed->setMaxValue(20); myDPaddleSpeed->setMinValue(1); myDPaddleSpeed->setMaxValue(20);
xpos = hSpace + myDPaddleSpeed->getWidth() + 5; xpos = HBORDER + myDPaddleSpeed->getWidth() + 5;
myDPaddleLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight, myDPaddleLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight, "");
"", TextAlign::Left);
wid.push_back(myDPaddleSpeed); wid.push_back(myDPaddleSpeed);
// Add paddle speed (mouse emulation) // Add paddle speed (mouse emulation)
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
myMPaddleSpeed = new SliderWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, myMPaddleSpeed = new SliderWidget(myTab, font, HBORDER, ypos,
"Mouse paddle sensitivity ", "Mouse paddle sensitivity ",
lwidth, kMPSpeedChanged); lwidth, kMPSpeedChanged);
myMPaddleSpeed->setMinValue(1); myMPaddleSpeed->setMaxValue(20); myMPaddleSpeed->setMinValue(1); myMPaddleSpeed->setMaxValue(20);
xpos = hSpace + myMPaddleSpeed->getWidth() + 5; xpos = HBORDER + myMPaddleSpeed->getWidth() + 5;
myMPaddleLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight, myMPaddleLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight, "");
"", TextAlign::Left);
wid.push_back(myMPaddleSpeed); wid.push_back(myMPaddleSpeed);
// Add trackball speed // Add trackball speed
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
myTrackBallSpeed = new SliderWidget(myTab, font, hSpace, ypos, pwidth, lineHeight, myTrackBallSpeed = new SliderWidget(myTab, font, HBORDER, ypos,
"Trackball sensitivity ", "Trackball sensitivity ",
lwidth, kTBSpeedChanged); lwidth, kTBSpeedChanged);
myTrackBallSpeed->setMinValue(1); myTrackBallSpeed->setMaxValue(20); myTrackBallSpeed->setMinValue(1); myTrackBallSpeed->setMaxValue(20);
xpos = hSpace + myTrackBallSpeed->getWidth() + 5; xpos = HBORDER + myTrackBallSpeed->getWidth() + 5;
myTrackBallLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight, myTrackBallLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight, "");
"", TextAlign::Left);
wid.push_back(myTrackBallSpeed); wid.push_back(myTrackBallSpeed);
// Add 'allow all 4 directions' for joystick // Add 'allow all 4 directions' for joystick
ypos += lineHeight + vGap*3; ypos += lineHeight + VGAP*3;
myAllowAll4 = new CheckboxWidget(myTab, font, hSpace, ypos, myAllowAll4 = new CheckboxWidget(myTab, font, HBORDER, ypos,
"Allow all 4 directions on joystick"); "Allow all 4 directions on joystick");
wid.push_back(myAllowAll4); wid.push_back(myAllowAll4);
// Grab mouse (in windowed mode) // Grab mouse (in windowed mode)
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
myGrabMouse = new CheckboxWidget(myTab, font, hSpace, ypos, myGrabMouse = new CheckboxWidget(myTab, font, HBORDER, ypos,
"Grab mouse in emulation mode"); "Grab mouse in emulation mode");
wid.push_back(myGrabMouse); wid.push_back(myGrabMouse);
#ifndef WINDOWED_SUPPORT #ifndef WINDOWED_SUPPORT
@ -215,38 +199,45 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
#endif #endif
// Enable/disable control key-combos // Enable/disable control key-combos
ypos += lineHeight + vGap; ypos += lineHeight + VGAP;
myCtrlCombo = new CheckboxWidget(myTab, font, hSpace, ypos, myCtrlCombo = new CheckboxWidget(myTab, font, HBORDER, ypos,
"Use Control key combos"); "Use Control key combos");
wid.push_back(myCtrlCombo); wid.push_back(myCtrlCombo);
ypos += lineHeight + VGAP;
// Stelladaptor mappings
mySAPort = new CheckboxWidget(myTab, font, HBORDER, ypos,
"Swap Stelladaptor ports");
wid.push_back(mySAPort);
int fwidth; int fwidth;
// Add EEPROM erase (part 1/2) // Add EEPROM erase (part 1/2)
ypos += vGap*4; ypos += VGAP*4;
fwidth = font.getStringWidth("AtariVox/SaveKey"); fwidth = font.getStringWidth("AtariVox/SaveKey");
lwidth = font.getStringWidth("AtariVox/SaveKey"); lwidth = font.getStringWidth("AtariVox/SaveKey");
new StaticTextWidget(myTab, font, _w - 14 - (fwidth + lwidth) / 2, ypos, new StaticTextWidget(myTab, font, _w - HBORDER - 4 - (fwidth + lwidth) / 2, ypos,
"AtariVox/SaveKey"); "AtariVox/SaveKey");
// Show joystick database // Show joystick database
ypos += lineHeight; ypos += lineHeight;
myJoyDlgButton = new ButtonWidget(myTab, font, hSpace, ypos, 20, myJoyDlgButton = new ButtonWidget(myTab, font, HBORDER, ypos, 20,
"Joystick database" + ELLIPSIS, kDBButtonPressed); "Joystick Database" + ELLIPSIS, kDBButtonPressed);
wid.push_back(myJoyDlgButton); wid.push_back(myJoyDlgButton);
// Add EEPROM erase (part 1/2) // Add EEPROM erase (part 1/2)
myEraseEEPROMButton = new ButtonWidget(myTab, font, _w - 14 - fwidth, ypos, myEraseEEPROMButton = new ButtonWidget(myTab, font, _w - HBORDER - 4 - fwidth, ypos,
fwidth, lineHeight+4, fwidth, lineHeight+4,
"Erase EEPROM", kEEButtonPressed); "Erase EEPROM", kEEButtonPressed);
wid.push_back(myEraseEEPROMButton);
// Add AtariVox serial port // Add AtariVox serial port
ypos += lineHeight + vGap*2; ypos += lineHeight + VGAP*2;
lwidth = font.getStringWidth("AVox serial port "); lwidth = font.getStringWidth("AVox serial port ");
fwidth = _w - 14 - hSpace - lwidth; fwidth = _w - HBORDER * 2 - 4 - lwidth;
new StaticTextWidget(myTab, font, hSpace, ypos, "AVox serial port "); new StaticTextWidget(myTab, font, HBORDER, ypos + 2, "AVox serial port ");
myAVoxPort = new EditTextWidget(myTab, font, hSpace + lwidth, ypos, myAVoxPort = new EditTextWidget(myTab, font, HBORDER + lwidth, ypos,
fwidth, fontHeight, ""); fwidth, fontHeight);
wid.push_back(myAVoxPort); wid.push_back(myAVoxPort);
@ -258,7 +249,7 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
void InputDialog::loadConfig() void InputDialog::loadConfig()
{ {
// Left & right ports // Left & right ports
mySAPort->setSelected(instance().settings().getString("saport"), "lr"); mySAPort->setState(instance().settings().getString("saport") == "rl");
// Use mouse as a controller // Use mouse as a controller
myMouseControl->setSelected( myMouseControl->setSelected(
@ -312,7 +303,7 @@ void InputDialog::loadConfig()
void InputDialog::saveConfig() void InputDialog::saveConfig()
{ {
// Left & right ports // Left & right ports
instance().eventHandler().mapStelladaptors(mySAPort->getSelectedTag().toString()); instance().eventHandler().mapStelladaptors(mySAPort->getState() ? "rl": "lr");
// Use mouse as a controller // Use mouse as a controller
const string& usemouse = myMouseControl->getSelectedTag().toString(); const string& usemouse = myMouseControl->getSelectedTag().toString();
@ -371,7 +362,7 @@ void InputDialog::setDefaults()
case 2: // Virtual devices case 2: // Virtual devices
{ {
// Left & right ports // Left & right ports
mySAPort->setSelected("lr"); mySAPort->setState(false);
// Use mouse as a controller // Use mouse as a controller
myMouseControl->setSelected("analog"); myMouseControl->setSelected("analog");
@ -520,8 +511,11 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd,
case kDBButtonPressed: case kDBButtonPressed:
if(!myJoyDialog) if(!myJoyDialog)
{
const GUI::Font& font = instance().frameBuffer().font();
myJoyDialog = make_unique<JoystickDialog> myJoyDialog = make_unique<JoystickDialog>
(this, instance().frameBuffer().font(), _w-60, _h-60); (this, font, font.getMaxCharWidth() * 56 + 20, font.getFontHeight() * 18 + 20);
}
myJoyDialog->show(); myJoyDialog->show();
break; break;
@ -539,7 +533,7 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd,
myConfirmMsg = make_unique<GUI::MessageBox> myConfirmMsg = make_unique<GUI::MessageBox>
(this, instance().frameBuffer().font(), msg, (this, instance().frameBuffer().font(), msg,
myMaxWidth, myMaxHeight, kConfirmEEEraseCmd, myMaxWidth, myMaxHeight, kConfirmEEEraseCmd,
"OK", "Cancel", false); "OK", "Cancel", "Erase EEPROM", false);
} }
myConfirmMsg->show(); myConfirmMsg->show();
break; break;

View File

@ -73,7 +73,7 @@ class InputDialog : public Dialog
EventMappingWidget* myEmulEventMapper; EventMappingWidget* myEmulEventMapper;
EventMappingWidget* myMenuEventMapper; EventMappingWidget* myMenuEventMapper;
PopUpWidget* mySAPort; CheckboxWidget* mySAPort;
PopUpWidget* myMouseControl; PopUpWidget* myMouseControl;
PopUpWidget* myCursorState; PopUpWidget* myCursorState;

View File

@ -29,8 +29,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& font, InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& font,
const StringList& labels) const StringList& labels, const string& title)
: Dialog(boss->instance(), boss->parent()), : Dialog(boss->instance(), boss->parent(), font, title),
CommandSender(boss), CommandSender(boss),
myEnableCenter(false), myEnableCenter(false),
myErrorFlag(false), myErrorFlag(false),
@ -43,8 +43,8 @@ InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& font,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& lfont, InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont, const GUI::Font& nfont,
const StringList& labels) const StringList& labels, const string& title)
: Dialog(boss->instance(), boss->parent()), : Dialog(boss->instance(), boss->parent(), lfont, title),
CommandSender(boss), CommandSender(boss),
myEnableCenter(false), myEnableCenter(false),
myErrorFlag(false), myErrorFlag(false),
@ -66,7 +66,7 @@ void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont,
// Calculate real dimensions // Calculate real dimensions
_w = fontWidth * 41; _w = fontWidth * 41;
_h = lineHeight * 4 + int(labels.size()) * (lineHeight + 5); _h = lineHeight * 4 + int(labels.size()) * (lineHeight + 5) + _th;
// Determine longest label // Determine longest label
for(i = 0; i < labels.size(); ++i) for(i = 0; i < labels.size(); ++i)
@ -80,7 +80,7 @@ void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont,
lwidth = lfont.getStringWidth(labels[maxIdx]); lwidth = lfont.getStringWidth(labels[maxIdx]);
// Create editboxes for all labels // Create editboxes for all labels
ypos = lineHeight; ypos = lineHeight + _th;
for(i = 0; i < labels.size(); ++i) for(i = 0; i < labels.size(); ++i)
{ {
xpos = 10; xpos = 10;
@ -98,9 +98,9 @@ void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont,
} }
xpos = 10; xpos = 10;
myTitle = new StaticTextWidget(this, lfont, xpos, ypos, _w - 2*xpos, fontHeight, myMessage = new StaticTextWidget(this, lfont, xpos, ypos, _w - 2*xpos, fontHeight,
"", TextAlign::Left); "", TextAlign::Left);
myTitle->setTextColor(kTextColorEm); myMessage->setTextColor(kTextColorEm);
addToFocusList(wid); addToFocusList(wid);
@ -148,9 +148,9 @@ void InputTextDialog::center()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void InputTextDialog::setTitle(const string& title) void InputTextDialog::setMessage(const string& title)
{ {
myTitle->setLabel(title); myMessage->setLabel(title);
myErrorFlag = true; myErrorFlag = true;
} }
@ -207,7 +207,7 @@ void InputTextDialog::handleCommand(CommandSender* sender, int cmd,
// Erase the invalid message once editing is restarted // Erase the invalid message once editing is restarted
if(myErrorFlag) if(myErrorFlag)
{ {
myTitle->setLabel(""); myMessage->setLabel("");
myErrorFlag = false; myErrorFlag = false;
} }
break; break;
@ -216,7 +216,6 @@ void InputTextDialog::handleCommand(CommandSender* sender, int cmd,
Dialog::handleCommand(sender, GuiObject::kCloseCmd, data, id); Dialog::handleCommand(sender, GuiObject::kCloseCmd, data, id);
break; break;
default: default:
Dialog::handleCommand(sender, cmd, data, id); Dialog::handleCommand(sender, cmd, data, id);
break; break;

View File

@ -30,9 +30,9 @@ class InputTextDialog : public Dialog, public CommandSender
{ {
public: public:
InputTextDialog(GuiObject* boss, const GUI::Font& font, InputTextDialog(GuiObject* boss, const GUI::Font& font,
const StringList& labels); const StringList& labels, const string& title = "");
InputTextDialog(GuiObject* boss, const GUI::Font& lfont, InputTextDialog(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont, const StringList& labels); const GUI::Font& nfont, const StringList& labels, const string& title = "");
virtual ~InputTextDialog() = default; virtual ~InputTextDialog() = default;
/** Place the input dialog onscreen and center it */ /** Place the input dialog onscreen and center it */
@ -47,7 +47,7 @@ class InputTextDialog : public Dialog, public CommandSender
void setTextFilter(const EditableWidget::TextFilter& f, int idx = 0); void setTextFilter(const EditableWidget::TextFilter& f, int idx = 0);
void setEmitSignal(int cmd) { myCmd = cmd; } void setEmitSignal(int cmd) { myCmd = cmd; }
void setTitle(const string& title); void setMessage(const string& title);
void setFocus(int idx = 0); void setFocus(int idx = 0);
@ -61,7 +61,7 @@ class InputTextDialog : public Dialog, public CommandSender
private: private:
vector<EditTextWidget*> myInput; vector<EditTextWidget*> myInput;
StaticTextWidget* myTitle; StaticTextWidget* myMessage;
bool myEnableCenter; bool myEnableCenter;
bool myErrorFlag; bool myErrorFlag;

View File

@ -27,16 +27,16 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font, JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font,
int max_w, int max_h) int max_w, int max_h)
: Dialog(boss->instance(), boss->parent(), 0, 0, max_w, max_h) : Dialog(boss->instance(), boss->parent(), font, "Joystick database", 0, 0, max_w, max_h)
{ {
int xpos, ypos; int xpos, ypos;
WidgetArray wid; WidgetArray wid;
int buttonWidth = font.getStringWidth("Close") + 20, int buttonWidth = font.getStringWidth("Remove ") + 20,
buttonHeight = font.getLineHeight() + 4; buttonHeight = font.getLineHeight() + 4;
// Joystick list // Joystick list
xpos = 10; ypos = 10; xpos = 10; ypos = 10 + _th;
int w = _w - 2 * xpos; int w = _w - 2 * xpos;
int h = _h - buttonHeight - ypos - 20; int h = _h - buttonHeight - ypos - 20;
myJoyList = new StringListWidget(this, font, xpos, ypos, w, h); myJoyList = new StringListWidget(this, font, xpos, ypos, w, h);
@ -45,11 +45,9 @@ JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font,
// Joystick ID // Joystick ID
ypos = _h - buttonHeight - 10; ypos = _h - buttonHeight - 10;
StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos, StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos+2, "Joystick ID ");
font.getStringWidth("Joystick ID "), font.getFontHeight(),
"Joystick ID ", TextAlign::Left);
xpos += t->getWidth() + 4; xpos += t->getWidth() + 4;
myJoyText = new EditTextWidget(this, font, xpos, ypos-2, myJoyText = new EditTextWidget(this, font, xpos, ypos,
font.getStringWidth("Unplugged")+8, font.getLineHeight(), ""); font.getStringWidth("Unplugged")+8, font.getLineHeight(), "");
myJoyText->setEditable(false); myJoyText->setEditable(false);
@ -60,7 +58,7 @@ JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font,
addOKWidget(myCloseBtn); addCancelWidget(myCloseBtn); addOKWidget(myCloseBtn); addCancelWidget(myCloseBtn);
buttonWidth = font.getStringWidth("Remove") + 20; buttonWidth = font.getStringWidth("Remove") + 20;
xpos -= buttonWidth + 5; xpos -= buttonWidth + 8;
myRemoveBtn = new ButtonWidget(this, font, xpos, ypos, myRemoveBtn = new ButtonWidget(this, font, xpos, ypos,
buttonWidth, buttonHeight, "Remove", kRemoveCmd); buttonWidth, buttonHeight, "Remove", kRemoveCmd);
myRemoveBtn->clearFlags(WIDGET_ENABLED); myRemoveBtn->clearFlags(WIDGET_ENABLED);

View File

@ -54,21 +54,22 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
myRomInfoWidget(nullptr), myRomInfoWidget(nullptr),
mySelectedItem(0) mySelectedItem(0)
{ {
const string ELLIPSIS = "\x1d";
const GUI::Font& font = instance().frameBuffer().launcherFont(); const GUI::Font& font = instance().frameBuffer().launcherFont();
const int fontWidth = font.getMaxCharWidth(), const int fontWidth = font.getMaxCharWidth(),
fontHeight = font.getFontHeight(), fontHeight = font.getFontHeight(),
lineHeight = font.getLineHeight(), lineHeight = font.getLineHeight(),
bwidth = (_w - 2 * 10 - 8 * (4 - 1)) / 4, bwidth = (_w - 2 * 10 - 8 * (4 - 1)) / 4,
bheight = font.getLineHeight() + 4; bheight = lineHeight + 4;
int xpos = 0, ypos = 0, lwidth = 0, lwidth2 = 0; int xpos = 0, ypos = 0, lwidth = 0, lwidth2 = 0;
WidgetArray wid; WidgetArray wid;
// Show game name // Show game name
lwidth = font.getStringWidth("Select an item from the list ..."); lwidth = font.getStringWidth("Select a ROM from the list" + ELLIPSIS);
xpos += 10; ypos += 8; xpos += 10; ypos += 8;
new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight, new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
"Select an item from the list ...", TextAlign::Left); "Select a ROM from the list" + ELLIPSIS);
lwidth2 = font.getStringWidth("XXXX items found"); lwidth2 = font.getStringWidth("XXXX items found");
xpos = _w - lwidth2 - 10; xpos = _w - lwidth2 - 10;
@ -81,14 +82,17 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
if(w >= 640) if(w >= 640)
{ {
int fwidth = std::min(15 * fontWidth, xpos - 20 - lwidth); int fwidth = std::min(15 * fontWidth, xpos - 20 - lwidth);
new StaticTextWidget(this, font, xpos - fwidth - 5 - font.getStringWidth("Filter "),
ypos, "Filter ");
xpos -= fwidth + 5; xpos -= fwidth + 5;
myPattern = new EditTextWidget(this, font, xpos, ypos, myPattern = new EditTextWidget(this, font, xpos, ypos - 2,
fwidth, fontHeight, ""); fwidth, lineHeight, "");
} }
// Add list with game titles // Add list with game titles
// Before we add the list, we need to know the size of the RomInfoWidget // Before we add the list, we need to know the size of the RomInfoWidget
xpos = 10; ypos += fontHeight + 5; xpos = 10; ypos += lineHeight + 4;
int romWidth = 0; int romWidth = 0;
int romSize = instance().settings().getInt("romviewer"); int romSize = instance().settings().getInt("romviewer");
if(romSize > 1 && w >= 1000 && h >= 760) if(romSize > 1 && w >= 1000 && h >= 760)
@ -96,9 +100,9 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
else if(romSize > 0 && w >= 640 && h >= 480) else if(romSize > 0 && w >= 640 && h >= 480)
romWidth = 365; romWidth = 365;
int listWidth = _w - (romWidth > 0 ? romWidth+5 : 0) - 20; int listWidth = _w - (romWidth > 0 ? romWidth+8 : 0) - 20;
myList = new StringListWidget(this, font, xpos, ypos, myList = new StringListWidget(this, font, xpos, ypos,
listWidth, _h - 35 - bheight - 2*fontHeight); listWidth, _h - 43 - bheight - fontHeight - lineHeight);
myList->setEditable(false); myList->setEditable(false);
wid.push_back(myList); wid.push_back(myList);
if(myPattern) wid.push_back(myPattern); // Add after the list for tab order if(myPattern) wid.push_back(myPattern); // Add after the list for tab order
@ -106,7 +110,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
// Add ROM info area (if enabled) // Add ROM info area (if enabled)
if(romWidth > 0) if(romWidth > 0)
{ {
xpos += myList->getWidth() + 5; xpos += myList->getWidth() + 8;
myRomInfoWidget = new RomInfoWidget(this, myRomInfoWidget = new RomInfoWidget(this,
romWidth < 660 ? instance().frameBuffer().smallFont() : romWidth < 660 ? instance().frameBuffer().smallFont() :
instance().frameBuffer().infoFont(), instance().frameBuffer().infoFont(),
@ -115,17 +119,17 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
// Add textfield to show current directory // Add textfield to show current directory
xpos = 10; xpos = 10;
xpos += 5; ypos += myList->getHeight() + 4; ypos += myList->getHeight() + 8;
lwidth = font.getStringWidth("Dir "); lwidth = font.getStringWidth("Path ");
myDirLabel = new StaticTextWidget(this, font, xpos, ypos+2, lwidth, fontHeight, myDirLabel = new StaticTextWidget(this, font, xpos, ypos+2, lwidth, fontHeight,
"Dir", TextAlign::Left); "Path", TextAlign::Left);
xpos += lwidth + 5; xpos += lwidth;
myDir = new EditTextWidget(this, font, xpos, ypos, _w - xpos - 10, lineHeight, ""); myDir = new EditTextWidget(this, font, xpos, ypos, _w - xpos - 10, lineHeight, "");
myDir->setEditable(false, true); myDir->setEditable(false, true);
myDir->clearFlags(WIDGET_RETAIN_FOCUS); myDir->clearFlags(WIDGET_RETAIN_FOCUS);
// Add four buttons at the bottom // Add four buttons at the bottom
xpos = 10; ypos += myDir->getHeight() + 4; xpos = 10; ypos += myDir->getHeight() + 8;
#ifndef BSPF_MAC_OSX #ifndef BSPF_MAC_OSX
myStartButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myStartButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
"Select", kLoadROMCmd); "Select", kLoadROMCmd);
@ -225,11 +229,12 @@ void LauncherDialog::loadConfig()
msg.push_back("Before you can start a game, you need to"); msg.push_back("Before you can start a game, you need to");
msg.push_back("specify where your ROMs are located."); msg.push_back("specify where your ROMs are located.");
msg.push_back(""); msg.push_back("");
msg.push_back("Click 'OK' to select a default ROM directory,"); msg.push_back("Click 'Default' to select a default ROM directory,");
msg.push_back("or 'Cancel' to browse the filesystem manually."); msg.push_back("or 'Browse' to browse the filesystem manually.");
myFirstRunMsg = make_unique<GUI::MessageBox> myFirstRunMsg = make_unique<GUI::MessageBox>
(this, instance().frameBuffer().font(), (this, instance().frameBuffer().font(),
msg, _w, _h, kFirstRunMsgChosenCmd); msg, _w, _h, kFirstRunMsgChosenCmd,
"Default", "Browse", "ROM directory");
} }
myFirstRunMsg->show(); myFirstRunMsg->show();
} }
@ -511,10 +516,9 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
case kFirstRunMsgChosenCmd: case kFirstRunMsgChosenCmd:
// Show a file browser, starting from the users' home directory // Show a file browser, starting from the users' home directory
if(!myRomDir) if(!myRomDir)
myRomDir = make_unique<BrowserDialog>(this, instance().frameBuffer().font(), _w, _h); myRomDir = make_unique<BrowserDialog>(this, instance().frameBuffer().font(),
_w, _h, "Select ROM directory");
myRomDir->show("Select ROM directory", "~", myRomDir->show("~", BrowserDialog::Directories, kStartupRomDirChosenCmd);
BrowserDialog::Directories, kStartupRomDirChosenCmd);
break; break;
case kStartupRomDirChosenCmd: case kStartupRomDirChosenCmd:

View File

@ -28,7 +28,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LauncherFilterDialog::LauncherFilterDialog(GuiObject* boss, const GUI::Font& font) LauncherFilterDialog::LauncherFilterDialog(GuiObject* boss, const GUI::Font& font)
: Dialog(boss->instance(), boss->parent()), : Dialog(boss->instance(), boss->parent(), font, "Filter file list"),
CommandSender(boss) CommandSender(boss)
{ {
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
@ -41,9 +41,9 @@ LauncherFilterDialog::LauncherFilterDialog(GuiObject* boss, const GUI::Font& fon
VariantList items; VariantList items;
// Set real dimensions // Set real dimensions
_w = 3 * buttonWidth;//lwidth + pwidth + fontWidth*5 + 10; _w = 3 * buttonWidth + 20 + 4 * 8;
xpos = 10; ypos = 10; xpos = 10; ypos = 10 + _th;
// Types of files to show // Types of files to show
VarList::push_back(items, "All files", "allfiles"); VarList::push_back(items, "All files", "allfiles");
@ -56,13 +56,13 @@ LauncherFilterDialog::LauncherFilterDialog(GuiObject* boss, const GUI::Font& fon
ypos += lineHeight + 10; ypos += lineHeight + 10;
// Different types of ROM extensions // Different types of ROM extensions
xpos = 40; xpos += font.getStringWidth("Show ");
myRomType[0] = new CheckboxWidget(this, font, xpos, ypos, ourRomTypes[0][0]); myRomType[0] = new CheckboxWidget(this, font, xpos, ypos, ourRomTypes[0][0]);
int rightcol = xpos + myRomType[0]->getWidth() + 10; int rightcol = xpos + myRomType[0]->getWidth() + 8 * 3;
myRomType[3] = new CheckboxWidget(this, font, xpos+rightcol, ypos, ourRomTypes[0][3]); myRomType[3] = new CheckboxWidget(this, font, rightcol, ypos, ourRomTypes[0][3]);
ypos += lineHeight + 4; ypos += lineHeight + 4;
myRomType[1] = new CheckboxWidget(this, font, xpos, ypos, ourRomTypes[0][1]); myRomType[1] = new CheckboxWidget(this, font, xpos, ypos, ourRomTypes[0][1]);
myRomType[4] = new CheckboxWidget(this, font, xpos+rightcol, ypos, ourRomTypes[0][4]); myRomType[4] = new CheckboxWidget(this, font, rightcol, ypos, ourRomTypes[0][4]);
ypos += lineHeight + 4; ypos += lineHeight + 4;
myRomType[2] = new CheckboxWidget(this, font, xpos, ypos, ourRomTypes[0][2]); myRomType[2] = new CheckboxWidget(this, font, xpos, ypos, ourRomTypes[0][2]);
ypos += lineHeight + 10; ypos += lineHeight + 10;
@ -70,11 +70,7 @@ LauncherFilterDialog::LauncherFilterDialog(GuiObject* boss, const GUI::Font& fon
_h = ypos + buttonHeight + 20; _h = ypos + buttonHeight + 20;
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
ButtonWidget* b; addDefaultsOKCancelBGroup(wid, font);
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font);
addToFocusList(wid); addToFocusList(wid);
} }
@ -181,7 +177,7 @@ void LauncherFilterDialog::saveConfig()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherFilterDialog::setDefaults() void LauncherFilterDialog::setDefaults()
{ {
handleFileTypeChange("allfiles"); handleFileTypeChange("allroms");
_dirty = true; _dirty = true;
} }

View File

@ -33,7 +33,7 @@
LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent, LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h, const GUI::Font& font, int max_w, int max_h,
bool uselargefont) bool uselargefont)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "System logs"),
myLogInfo(nullptr) myLogInfo(nullptr)
{ {
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
@ -48,7 +48,7 @@ LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent,
_h = max_h; _h = max_h;
// Test listing of the log output // Test listing of the log output
xpos = 10; ypos = 10; xpos = 10; ypos = 10 + _th;
myLogInfo = new StringListWidget(this, uselargefont ? font : myLogInfo = new StringListWidget(this, uselargefont ? font :
instance().frameBuffer().infoFont(), xpos, ypos, _w - 2 * xpos, instance().frameBuffer().infoFont(), xpos, ypos, _w - 2 * xpos,
_h - buttonHeight - ypos - 20 - 2 * lineHeight, false); _h - buttonHeight - ypos - 20 - 2 * lineHeight, false);
@ -57,7 +57,6 @@ LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent,
ypos += myLogInfo->getHeight() + 8; ypos += myLogInfo->getHeight() + 8;
// Level of logging (how much info to print) // Level of logging (how much info to print)
xpos += 20;
VariantList items; VariantList items;
VarList::push_back(items, "None", "0"); VarList::push_back(items, "None", "0");
VarList::push_back(items, "Basic", "1"); VarList::push_back(items, "Basic", "1");
@ -69,11 +68,11 @@ LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent,
wid.push_back(myLogLevel); wid.push_back(myLogLevel);
// Should log output also be shown on the console? // Should log output also be shown on the console?
xpos += myLogLevel->getWidth() + 30; xpos += myLogLevel->getWidth() + 32;
myLogToConsole = new CheckboxWidget(this, font, xpos, ypos, "Print to console"); myLogToConsole = new CheckboxWidget(this, font, xpos, ypos + 1, "Print to console");
wid.push_back(myLogToConsole); wid.push_back(myLogToConsole);
// Add Defaults, OK and Cancel buttons // Add Save, OK and Cancel buttons
ButtonWidget* b; ButtonWidget* b;
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Save log to disk", buttonWidth, buttonHeight, "Save log to disk",

View File

@ -29,8 +29,9 @@ namespace GUI {
MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font, MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font,
const StringList& text, int max_w, int max_h, int cmd, const StringList& text, int max_w, int max_h, int cmd,
const string& okText, const string& cancelText, const string& okText, const string& cancelText,
const string& title,
bool focusOKButton) bool focusOKButton)
: Dialog(boss->instance(), boss->parent(), 0, 0, max_w, max_h), : Dialog(boss->instance(), boss->parent(), font, title, 0, 0, max_w, max_h),
CommandSender(boss), CommandSender(boss),
myCmd(cmd) myCmd(cmd)
{ {
@ -45,9 +46,10 @@ MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font,
MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font, MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font,
const string& text, int max_w, int max_h, int cmd, const string& text, int max_w, int max_h, int cmd,
const string& okText, const string& cancelText, const string& okText, const string& cancelText,
const string& title,
bool focusOKButton) bool focusOKButton)
: MessageBox(boss, font, StringParser(text).stringList(), max_w, max_h, : MessageBox(boss, font, StringParser(text).stringList(), max_w, max_h,
cmd, okText, cancelText, focusOKButton) cmd, okText, cancelText, title, focusOKButton)
{ {
} }
@ -64,9 +66,9 @@ void MessageBox::addText(const GUI::Font& font, const StringList& text)
for(const auto& s: text) for(const auto& s: text)
str_w = std::max(int(s.length()), str_w); str_w = std::max(int(s.length()), str_w);
_w = std::min(str_w * fontWidth + 20, _w); _w = std::min(str_w * fontWidth + 20, _w);
_h = std::min(uInt32((text.size() + 2) * lineHeight + 20), uInt32(_h)); _h = std::min(uInt32((text.size() + 2) * lineHeight + 20 + _th), uInt32(_h));
xpos = 10; ypos = 10; xpos = 10; ypos = 10 + _th;
for(const auto& s: text) for(const auto& s: text)
{ {
new StaticTextWidget(this, font, xpos, ypos, _w - 20, new StaticTextWidget(this, font, xpos, ypos, _w - 20,

View File

@ -37,10 +37,12 @@ class MessageBox : public Dialog, public CommandSender
MessageBox(GuiObject* boss, const GUI::Font& font, const StringList& text, MessageBox(GuiObject* boss, const GUI::Font& font, const StringList& text,
int max_w, int max_h, int cmd = 0, int max_w, int max_h, int cmd = 0,
const string& okText = "OK", const string& cancelText = "Cancel", const string& okText = "OK", const string& cancelText = "Cancel",
const string& title = "",
bool focusOKButton = true); bool focusOKButton = true);
MessageBox(GuiObject* boss, const GUI::Font& font, const string& text, MessageBox(GuiObject* boss, const GUI::Font& font, const string& text,
int max_w, int max_h, int cmd = 0, int max_w, int max_h, int cmd = 0,
const string& okText = "OK", const string& cancelText = "Cancel", const string& okText = "OK", const string& cancelText = "Cancel",
const string& title = "",
bool focusOKButton = true); bool focusOKButton = true);
virtual ~MessageBox() = default; virtual ~MessageBox() = default;

View File

@ -51,14 +51,17 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
myMode(mode) myMode(mode)
{ {
const GUI::Font& font = instance().frameBuffer().font(); const GUI::Font& font = instance().frameBuffer().font();
const int buttonWidth = font.getStringWidth("Developer Settings" + ELLIPSIS) + 20, initTitle(font, "Options");
const int buttonWidth = font.getStringWidth("Game Properties" + ELLIPSIS) + 20,
buttonHeight = font.getLineHeight() + 6, buttonHeight = font.getLineHeight() + 6,
rowHeight = font.getLineHeight() + 10; rowHeight = font.getLineHeight() + 10;
const int VBORDER = 10 + _th;
_w = 2 * buttonWidth + 30; _w = 2 * buttonWidth + 30;
_h = 7 * rowHeight + 15; _h = 7 * rowHeight + 15 + _th;
int xoffset = 10, yoffset = 10; int xoffset = 10, yoffset = VBORDER;
WidgetArray wid; WidgetArray wid;
ButtonWidget* b = nullptr; ButtonWidget* b = nullptr;
@ -70,46 +73,47 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
return bw; return bw;
}; };
b = ADD_OD_BUTTON("Video Settings" + ELLIPSIS, kVidCmd); b = ADD_OD_BUTTON("Video" + ELLIPSIS, kVidCmd);
wid.push_back(b); wid.push_back(b);
b = ADD_OD_BUTTON("Audio Settings" + ELLIPSIS, kAudCmd); b = ADD_OD_BUTTON("Audio" + ELLIPSIS, kAudCmd);
#ifndef SOUND_SUPPORT #ifndef SOUND_SUPPORT
b->clearFlags(WIDGET_ENABLED); b->clearFlags(WIDGET_ENABLED);
#endif #endif
wid.push_back(b); wid.push_back(b);
b = ADD_OD_BUTTON("Input Settings" + ELLIPSIS, kInptCmd); b = ADD_OD_BUTTON("Input" + ELLIPSIS, kInptCmd);
wid.push_back(b); wid.push_back(b);
b = ADD_OD_BUTTON("UI Settings" + ELLIPSIS, kUsrIfaceCmd); b = ADD_OD_BUTTON("User Interface" + ELLIPSIS, kUsrIfaceCmd);
wid.push_back(b); wid.push_back(b);
b = ADD_OD_BUTTON("Snapshot Settings" + ELLIPSIS, kSnapCmd); b = ADD_OD_BUTTON("Snapshots" + ELLIPSIS, kSnapCmd);
wid.push_back(b); wid.push_back(b);
b = ADD_OD_BUTTON("Config Paths" + ELLIPSIS, kCfgPathsCmd); b = ADD_OD_BUTTON("Paths" + ELLIPSIS, kCfgPathsCmd);
wid.push_back(b);
b = ADD_OD_BUTTON("Developer" + ELLIPSIS, kDevelopCmd);
wid.push_back(b); wid.push_back(b);
myRomAuditButton = ADD_OD_BUTTON("Audit ROMs" + ELLIPSIS, kAuditCmd);
wid.push_back(myRomAuditButton);
// Move to second column // Move to second column
xoffset += buttonWidth + 10; yoffset = 10; xoffset += buttonWidth + 10; yoffset = VBORDER;
myGameInfoButton = ADD_OD_BUTTON("Game Properties" + ELLIPSIS, kInfoCmd); myGameInfoButton = ADD_OD_BUTTON("Game Properties" + ELLIPSIS, kInfoCmd);
wid.push_back(myGameInfoButton); wid.push_back(myGameInfoButton);
myCheatCodeButton = ADD_OD_BUTTON("Cheat Code" + ELLIPSIS, kCheatCmd); myCheatCodeButton = ADD_OD_BUTTON("Cheat Codes" + ELLIPSIS, kCheatCmd);
#ifndef CHEATCODE_SUPPORT #ifndef CHEATCODE_SUPPORT
myCheatCodeButton->clearFlags(WIDGET_ENABLED); myCheatCodeButton->clearFlags(WIDGET_ENABLED);
#endif #endif
wid.push_back(myCheatCodeButton); wid.push_back(myCheatCodeButton);
b = ADD_OD_BUTTON("System Logs" + ELLIPSIS, kLoggerCmd); myRomAuditButton = ADD_OD_BUTTON("Audit ROMs" + ELLIPSIS, kAuditCmd);
wid.push_back(b); wid.push_back(myRomAuditButton);
b = ADD_OD_BUTTON("Developer Settings" + ELLIPSIS, kDevelopCmd); b = ADD_OD_BUTTON("System Logs" + ELLIPSIS, kLoggerCmd);
wid.push_back(b); wid.push_back(b);
b = ADD_OD_BUTTON("Help" + ELLIPSIS, kHelpCmd); b = ADD_OD_BUTTON("Help" + ELLIPSIS, kHelpCmd);
@ -118,7 +122,7 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
b = ADD_OD_BUTTON("About" + ELLIPSIS, kAboutCmd); b = ADD_OD_BUTTON("About" + ELLIPSIS, kAboutCmd);
wid.push_back(b); wid.push_back(b);
b = ADD_OD_BUTTON("Exit Menu", kExitCmd); b = ADD_OD_BUTTON("Close", kExitCmd);
wid.push_back(b); wid.push_back(b);
addCancelWidget(b); addCancelWidget(b);

View File

@ -23,19 +23,7 @@
#include "DialogContainer.hxx" #include "DialogContainer.hxx"
#include "PopUpWidget.hxx" #include "PopUpWidget.hxx"
// Little up/down arrow // Little down arrow
#ifndef FLAT_UI
static uInt32 up_down_arrows[8] = {
0b00000000,
0b00001000,
0b00011100,
0b00111110,
0b00000000,
0b00111110,
0b00011100,
0b00001000,
};
#else
static uInt32 down_arrow[8] = { static uInt32 down_arrow[8] = {
0b100000001, 0b100000001,
0b110000011, 0b110000011,
@ -46,7 +34,6 @@ static uInt32 down_arrow[8] = {
0b000010000, 0b000010000,
0b000000000 0b000000000
}; };
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font, PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font,
@ -67,11 +54,7 @@ PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font,
if(!_label.empty() && _labelWidth == 0) if(!_label.empty() && _labelWidth == 0)
_labelWidth = _font.getStringWidth(_label); _labelWidth = _font.getStringWidth(_label);
#ifndef FLAT_UI
_w = w + _labelWidth + 15;
#else
_w = w + _labelWidth + 23; _w = w + _labelWidth + 23;
#endif
// vertically center the arrows and text // vertically center the arrows and text
myTextY = (_h - _font.getFontHeight()) / 2; myTextY = (_h - _font.getFontHeight()) / 2;
@ -157,7 +140,6 @@ void PopUpWidget::handleMouseWheel(int x, int y, int direction)
} }
} }
#ifdef FLAT_UI
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::handleMouseEntered() void PopUpWidget::handleMouseEntered()
{ {
@ -171,7 +153,6 @@ void PopUpWidget::handleMouseLeft()
clearFlags(WIDGET_HILITED); clearFlags(WIDGET_HILITED);
setDirty(); setDirty();
} }
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PopUpWidget::handleEvent(Event::Type e) bool PopUpWidget::handleEvent(Event::Type e)
@ -221,32 +202,14 @@ void PopUpWidget::drawWidget(bool hilite)
int x = _x + _labelWidth; int x = _x + _labelWidth;
int w = _w - _labelWidth; int w = _w - _labelWidth;
#ifndef FLAT_UI
// Draw the label, if any
if(_labelWidth > 0)
s.drawString(_font, _label, _x, _y + myTextY, _labelWidth,
isEnabled() ? _textcolor : uInt32(kColor), TextAlign::Right);
// Draw a thin frame around us.
s.hLine(x, _y, x + w - 1, kColor);
s.hLine(x, _y +_h-1, x + w - 1, kShadowColor);
s.vLine(x, _y, _y+_h-1, kColor);
s.vLine(x + w - 1, _y, _y +_h - 1, kShadowColor);
// Fill the background
s.fillRect(x + 1, _y + 1, w - 2, _h - 2, _changed ? kDbgChangedColor : kWidColor);
// Draw an arrow pointing down at the right end to signal this is a dropdown/popup
s.drawBitmap(up_down_arrows, x + w - 10, _y + myArrowsY,
!isEnabled() ? kColor : hilite ? kTextColorHi : kTextColor);
#else
// Draw the label, if any // Draw the label, if any
if(_labelWidth > 0) if(_labelWidth > 0)
s.drawString(_font, _label, _x, _y + myTextY, _labelWidth, s.drawString(_font, _label, _x, _y + myTextY, _labelWidth,
isEnabled() ? _textcolor : uInt32(kColor), TextAlign::Left); isEnabled() ? _textcolor : uInt32(kColor), TextAlign::Left);
// Draw a thin frame around us. // Draw a thin frame around us.
s.frameRect(x, _y, w, _h, kColor); s.frameRect(x, _y, w, _h, isEnabled() && hilite ? kWidColorHi : kColor);
s.frameRect(x + w - 16, _y + 1, 15, _h - 2, isEnabled() && hilite ? kTextColorHi : kBGColorLo); s.frameRect(x + w - 16, _y + 1, 15, _h - 2, isEnabled() && hilite ? kWidColorHi : kBGColorLo);
// Fill the background // Fill the background
s.fillRect(x + 1, _y + 1, w - 17, _h - 2, _changed ? kDbgChangedColor : kWidColor); s.fillRect(x + 1, _y + 1, w - 17, _h - 2, _changed ? kDbgChangedColor : kWidColor);
@ -254,7 +217,6 @@ void PopUpWidget::drawWidget(bool hilite)
// Draw an arrow pointing down at the right end to signal this is a dropdown/popup // Draw an arrow pointing down at the right end to signal this is a dropdown/popup
s.drawBitmap(down_arrow, x + w - 13, _y + myArrowsY + 1, s.drawBitmap(down_arrow, x + w - 13, _y + myArrowsY + 1,
!isEnabled() ? kColor : kTextColor, 9u, 8u); !isEnabled() ? kColor : kTextColor, 9u, 8u);
#endif
// Draw the selected entry, if any // Draw the selected entry, if any
const string& name = myMenu->getSelectedName(); const string& name = myMenu->getSelectedName();

View File

@ -64,10 +64,8 @@ class PopUpWidget : public Widget, public CommandSender
protected: protected:
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseDown(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;
#ifdef FLAT_UI
void handleMouseEntered() override; void handleMouseEntered() override;
void handleMouseLeft() override; void handleMouseLeft() override;
#endif
bool handleEvent(Event::Type e) override; bool handleEvent(Event::Type e) override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
void drawWidget(bool hilite) override; void drawWidget(bool hilite) override;

View File

@ -21,63 +21,6 @@
#include "RadioButtonWidget.hxx" #include "RadioButtonWidget.hxx"
/* Radiobutton bitmaps */ /* Radiobutton bitmaps */
#ifndef FLAT_UI
static uInt32 radio_img_outercircle[14] =
{
0b00001111110000,
0b00111111111100,
0b01110000001110,
0b01100000000110,
0b11000000000011,
0b11000000000011,
0b11000000000011,
0b11000000000011,
0b11000000000011,
0b11000000000011,
0b01100000000110,
0b01110000001110,
0b00111111111100,
0b00001111110000
};
static uInt32 radio_img_innercircle[10] =
{
0b0011111100,
0b0111111110,
0b1111111111,
0b1111111111,
0b1111111111,
0b1111111111,
0b1111111111,
0b1111111111,
0b0111111110,
0b0011111100
};
static uInt32 radio_img_active[8] =
{
0b00111100,
0b01111110,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b01111110,
0b00111100
};
static uInt32 radio_img_inactive[8] =
{
0b00111100,
0b01111110,
0b11100111,
0b11000011,
0b11000011,
0b11100111,
0b01111110,
0b00111100
};
#else
static uInt32 radio_img_outercircle[14] = static uInt32 radio_img_outercircle[14] =
{ {
0b00001111110000, 0b00001111110000,
@ -139,7 +82,6 @@ static uInt32 radio_img_inactive[10] =
0b0111111110, 0b0111111110,
0b0011111100 0b0011111100
}; };
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RadioButtonWidget::RadioButtonWidget(GuiObject* boss, const GUI::Font& font, RadioButtonWidget::RadioButtonWidget(GuiObject* boss, const GUI::Font& font,
@ -217,19 +159,8 @@ void RadioButtonWidget::drawWidget(bool hilite)
{ {
FBSurface& s = _boss->dialog().surface(); FBSurface& s = _boss->dialog().surface();
#ifndef FLAT_UI
// Draw the outer bounding circle // Draw the outer bounding circle
s.drawBitmap(radio_img_outercircle, _x, _y + _boxY, kShadowColor, 14, 14); s.drawBitmap(radio_img_outercircle, _x, _y + _boxY, hilite ? kWidColorHi : kColor, 14, 14);
// Draw the inner bounding circle with enabled color
s.drawBitmap(radio_img_innercircle, _x + 2, _y + _boxY + 2, isEnabled() ? _bgcolor : kColor, 10, 10);
// draw state
if(_state)
s.drawBitmap(_img, _x + 3, _y + _boxY + 3, isEnabled() ? kCheckColor : kShadowColor);
#else
// Draw the outer bounding circle
s.drawBitmap(radio_img_outercircle, _x, _y + _boxY, hilite ? kScrollColorHi : kShadowColor, 14, 14);
// Draw the inner bounding circle with enabled color // Draw the inner bounding circle with enabled color
s.drawBitmap(radio_img_innercircle, _x + 1, _y + _boxY + 1, isEnabled() s.drawBitmap(radio_img_innercircle, _x + 1, _y + _boxY + 1, isEnabled()
@ -238,9 +169,8 @@ void RadioButtonWidget::drawWidget(bool hilite)
// draw state // draw state
if(_state) if(_state)
s.drawBitmap(_img, _x + 2, _y + _boxY + 2, isEnabled() s.drawBitmap(_img, _x + 2, _y + _boxY + 2, isEnabled()
? hilite ? kScrollColorHi : kCheckColor ? hilite ? kWidColorHi : kCheckColor
: kShadowColor, 10); : kColor, 10);
#endif
// Finally draw the label // Finally draw the label
s.drawString(_font, _label, _x + 20, _y + _textY, _w, s.drawString(_font, _label, _x + 20, _y + _textY, _w,

View File

@ -35,13 +35,13 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RomAuditDialog::RomAuditDialog(OSystem& osystem, DialogContainer& parent, RomAuditDialog::RomAuditDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h) const GUI::Font& font, int max_w, int max_h)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "Audit ROMs"),
myConfirmMsg(nullptr), myConfirmMsg(nullptr),
myMaxWidth(max_w), myMaxWidth(max_w),
myMaxHeight(max_h) myMaxHeight(max_h)
{ {
const int vBorder = 10; const int VBORDER = 10 + _th;
const int hBorder = 10; const int HBORDER = 10;
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth(), fontWidth = font.getMaxCharWidth(),
@ -49,48 +49,48 @@ RomAuditDialog::RomAuditDialog(OSystem& osystem, DialogContainer& parent,
buttonWidth = font.getStringWidth("Audit path" + ELLIPSIS) + 20, buttonWidth = font.getStringWidth("Audit path" + ELLIPSIS) + 20,
buttonHeight = font.getLineHeight() + 4, buttonHeight = font.getLineHeight() + 4,
lwidth = font.getStringWidth("ROMs without properties (skipped) "); lwidth = font.getStringWidth("ROMs without properties (skipped) ");
int xpos, ypos = vBorder; int xpos, ypos = VBORDER;
WidgetArray wid; WidgetArray wid;
// Set real dimensions // Set real dimensions
_w = 54 * fontWidth + 10; _w = 64 * fontWidth + HBORDER * 2;
_h = 7 * (lineHeight + 4) + 10; _h = 7 * (lineHeight + 4) + VBORDER;
// Audit path // Audit path
ButtonWidget* romButton = ButtonWidget* romButton =
new ButtonWidget(this, font, hBorder, ypos, buttonWidth, buttonHeight, new ButtonWidget(this, font, HBORDER, ypos, buttonWidth, buttonHeight,
"Audit path" + ELLIPSIS, kChooseAuditDirCmd); "Audit path" + ELLIPSIS, kChooseAuditDirCmd);
wid.push_back(romButton); wid.push_back(romButton);
xpos = hBorder + buttonWidth + 10; xpos = HBORDER + buttonWidth + 8;
myRomPath = new EditTextWidget(this, font, xpos, ypos + 2, myRomPath = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - hBorder, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(myRomPath); wid.push_back(myRomPath);
// Show results of ROM audit // Show results of ROM audit
ypos += buttonHeight + 16; ypos += buttonHeight + 16;
new StaticTextWidget(this, font, hBorder, ypos, lwidth, fontHeight, new StaticTextWidget(this, font, HBORDER, ypos, lwidth, fontHeight,
"ROMs with properties (renamed) ", TextAlign::Left); "ROMs with properties (renamed) ", TextAlign::Left);
myResults1 = new EditTextWidget(this, font, hBorder + lwidth, ypos - 2, myResults1 = new EditTextWidget(this, font, HBORDER + lwidth, ypos - 2,
_w - hBorder*2 - lwidth, lineHeight, ""); fontWidth * 6, lineHeight, "");
myResults1->setEditable(false, true); myResults1->setEditable(false, true);
ypos += buttonHeight; ypos += buttonHeight;
new StaticTextWidget(this, font, hBorder, ypos, lwidth, fontHeight, new StaticTextWidget(this, font, HBORDER, ypos, lwidth, fontHeight,
"ROMs without properties (skipped) ", TextAlign::Left); "ROMs without properties (skipped) ", TextAlign::Left);
myResults2 = new EditTextWidget(this, font, hBorder + lwidth, ypos - 2, myResults2 = new EditTextWidget(this, font, HBORDER + lwidth, ypos - 2,
_w - hBorder*2 - lwidth, lineHeight, ""); fontWidth * 6, lineHeight, "");
myResults2->setEditable(false, true); myResults2->setEditable(false, true);
ypos += buttonHeight + 8; ypos += buttonHeight + 8;
new StaticTextWidget(this, font, hBorder, ypos, _w - 20, fontHeight, new StaticTextWidget(this, font, HBORDER, ypos, _w - 20, fontHeight,
"(*) WARNING: operation cannot be undone!", "(*) WARNING: Operation cannot be undone!",
TextAlign::Left); TextAlign::Left);
// Add OK and Cancel buttons // Add OK and Cancel buttons
addOKCancelBGroup(wid, font, "Audit", "Done"); addOKCancelBGroup(wid, font, "Audit", "Close");
addBGroupToFocusList(wid); addBGroupToFocusList(wid);
// Create file browser dialog // Create file browser dialog
myBrowser = make_unique<BrowserDialog>(this, font, myMaxWidth, myMaxHeight); myBrowser = make_unique<BrowserDialog>(this, font, myMaxWidth, myMaxHeight, "Select ROM directory to audit");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -189,7 +189,7 @@ void RomAuditDialog::handleCommand(CommandSender* sender, int cmd,
myConfirmMsg = make_unique<GUI::MessageBox> myConfirmMsg = make_unique<GUI::MessageBox>
(this, instance().frameBuffer().font(), msg, (this, instance().frameBuffer().font(), msg,
myMaxWidth, myMaxHeight, kConfirmAuditCmd, myMaxWidth, myMaxHeight, kConfirmAuditCmd,
"OK", "Cancel", false); "OK", "Cancel", "ROM Audit", false);
} }
myConfirmMsg->show(); myConfirmMsg->show();
break; break;
@ -200,7 +200,7 @@ void RomAuditDialog::handleCommand(CommandSender* sender, int cmd,
break; break;
case kChooseAuditDirCmd: case kChooseAuditDirCmd:
myBrowser->show("Select ROM directory to audit", myRomPath->getText(), myBrowser->show(myRomPath->getText(),
BrowserDialog::Directories, kAuditDirChosenCmd); BrowserDialog::Directories, kAuditDirChosenCmd);
break; break;

View File

@ -142,9 +142,9 @@ void RomInfoWidget::drawWidget(bool hilite)
const int yoff = myAvail.h + 10; const int yoff = myAvail.h + 10;
s.fillRect(_x+2, _y+2, _w-4, _h-4, kWidColor); s.fillRect(_x+2, _y+2, _w-4, _h-4, kDlgColor);
s.box(_x, _y, _w, _h, kColor, kShadowColor); s.frameRect(_x, _y, _w, _h, kColor);
s.box(_x, _y+yoff, _w, _h-yoff, kColor, kShadowColor); s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor);
if(!myHaveProperties) return; if(!myHaveProperties) return;
@ -167,10 +167,10 @@ void RomInfoWidget::drawWidget(bool hilite)
s.drawString(font, mySurfaceErrorMsg, x, y, _w - 10, _textcolor); s.drawString(font, mySurfaceErrorMsg, x, y, _w - 10, _textcolor);
} }
int xpos = _x + 5, ypos = _y + yoff + 10; int xpos = _x + 8, ypos = _y + yoff + 10;
for(const auto& info: myRomInfo) for(const auto& info: myRomInfo)
{ {
s.drawString(_font, info, xpos, ypos, _w - 10, _textcolor); s.drawString(_font, info, xpos, ypos, _w - 16, _textcolor);
ypos += _font.getLineHeight(); ypos += _font.getLineHeight();
} }
} }

View File

@ -32,26 +32,26 @@
// Up arrow // Up arrow
static uInt32 up_arrow[8] = { static uInt32 up_arrow[8] = {
0b00011000, 0b00000000,
0b00011000, 0b00010000,
0b00111100, 0b00111000,
0b00111100, 0b01111100,
0b01111110, 0b11101110,
0b01111110, 0b11000110,
0b11111111, 0b10000010,
0b11111111 0b00000000
}; };
// Down arrow // Down arrow
static uInt32 down_arrow[8] = { static uInt32 down_arrow[8] = {
0b11111111, 0b00000000,
0b11111111, 0b10000010,
0b01111110, 0b11000110,
0b01111110, 0b11101110,
0b00111100, 0b01111100,
0b00111100, 0b00111000,
0b00011000, 0b00010000,
0b00011000 0b00000000
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -101,11 +101,11 @@ void ScrollBarWidget::handleMouseDown(int x, int y, MouseButton b,
} }
else if(y < _sliderPos) else if(y < _sliderPos)
{ {
_currentPos -= _entriesPerPage; _currentPos -= _entriesPerPage - 1;
} }
else if(y >= _sliderPos + _sliderHeight) else if(y >= _sliderPos + _sliderHeight)
{ {
_currentPos += _entriesPerPage; _currentPos += _entriesPerPage - 1;
} }
else else
{ {
@ -209,6 +209,7 @@ void ScrollBarWidget::checkBounds(int old_pos)
void ScrollBarWidget::handleMouseEntered() void ScrollBarWidget::handleMouseEntered()
{ {
setFlags(WIDGET_HILITED); setFlags(WIDGET_HILITED);
setDirty();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -216,6 +217,7 @@ void ScrollBarWidget::handleMouseLeft()
{ {
_part = kNoPart; _part = kNoPart;
clearFlags(WIDGET_HILITED); clearFlags(WIDGET_HILITED);
setDirty();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -250,31 +252,28 @@ void ScrollBarWidget::drawWidget(bool hilite)
int bottomY = _y + _h; int bottomY = _y + _h;
bool isSinglePage = (_numEntries <= _entriesPerPage); bool isSinglePage = (_numEntries <= _entriesPerPage);
s.frameRect(_x, _y, _w, _h, kShadowColor); s.frameRect(_x, _y, _w, _h, hilite ? kWidColorHi : kColor);
if(_draggingPart != kNoPart) if(_draggingPart != kNoPart)
_part = _draggingPart; _part = _draggingPart;
// Up arrow // Up arrow
s.frameRect(_x, _y, _w, UP_DOWN_BOX_HEIGHT, kColor); if(hilite && _part == kUpArrowPart)
s.drawBitmap(up_arrow, _x+3, _y+5, isSinglePage ? kColor : s.fillRect(_x + 1, _y + 1, _w - 2, UP_DOWN_BOX_HEIGHT - 2, kScrollColor);
(hilite && _part == kUpArrowPart) ? kScrollColorHi : kScrollColor, 8); s.drawBitmap(up_arrow, _x+4, _y+5, isSinglePage ? kColor :
(hilite && _part == kUpArrowPart) ? kWidColor : kTextColor, 8);
// Down arrow // Down arrow
s.frameRect(_x, bottomY - UP_DOWN_BOX_HEIGHT, _w, UP_DOWN_BOX_HEIGHT, kColor); if(hilite && _part == kDownArrowPart)
s.drawBitmap(down_arrow, _x+3, bottomY - UP_DOWN_BOX_HEIGHT + 5, isSinglePage ? kColor : s.fillRect(_x + 1, bottomY - UP_DOWN_BOX_HEIGHT + 1, _w - 2, UP_DOWN_BOX_HEIGHT - 2, kScrollColor);
(hilite && _part == kDownArrowPart) ? kScrollColorHi : kScrollColor, 8); s.drawBitmap(down_arrow, _x+4, bottomY - UP_DOWN_BOX_HEIGHT + 5, isSinglePage ? kColor :
(hilite && _part == kDownArrowPart) ? kWidColor : kTextColor, 8);
// Slider // Slider
if(!isSinglePage) if(!isSinglePage)
{ {
s.fillRect(_x, _y + _sliderPos, _w, _sliderHeight, s.fillRect(_x + 1, _y + _sliderPos - 1, _w - 2, _sliderHeight + 2,
(hilite && _part == kSliderPart) ? kScrollColorHi : kScrollColor); (hilite && _part == kSliderPart) ? kScrollColorHi : kScrollColor);
s.frameRect(_x, _y + _sliderPos, _w, _sliderHeight, kColor);
int y = _y + _sliderPos + _sliderHeight / 2;
s.hLine(_x + 2, y - 2, _x + _w - 3, kWidColor);
s.hLine(_x + 2, y, _x + _w - 3, kWidColor);
s.hLine(_x + 2, y + 2, _x + _w - 3, kWidColor);
} }
} }

View File

@ -25,7 +25,7 @@ class GuiObject;
#include "bspf.hxx" #include "bspf.hxx"
enum { enum {
kScrollBarWidth = 14 kScrollBarWidth = 15
}; };
class ScrollBarWidget : public Widget, public CommandSender class ScrollBarWidget : public Widget, public CommandSender

View File

@ -21,104 +21,87 @@
#include "FSNode.hxx" #include "FSNode.hxx"
#include "Font.hxx" #include "Font.hxx"
#include "LauncherDialog.hxx" #include "LauncherDialog.hxx"
#include "PopUpWidget.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include "SnapshotDialog.hxx" #include "SnapshotDialog.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent, SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font) const GUI::Font& font)
: Dialog(osystem, parent), : Dialog(osystem, parent, font, "Snapshot settings"),
myFont(font) myFont(font)
{ {
const int VBORDER = 10;
const int HBORDER = 10;
const int INDENT = 16;
const int V_GAP = 4;
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth(), fontWidth = font.getMaxCharWidth(),
buttonWidth = font.getStringWidth("Save path" + ELLIPSIS) + 20, buttonWidth = font.getStringWidth("Save path" + ELLIPSIS) + 20,
buttonHeight = font.getLineHeight() + 4; buttonHeight = font.getLineHeight() + 4;
const int vBorder = 10; int xpos, ypos, fwidth;
int xpos, ypos, lwidth, fwidth;
WidgetArray wid; WidgetArray wid;
ButtonWidget* b; ButtonWidget* b;
// Set real dimensions // Set real dimensions
_w = 53 * fontWidth + 8; _w = 64 * fontWidth + HBORDER * 2;
_h = 10 * (lineHeight + 4) + 10; _h = 10 * (lineHeight + 4) + VBORDER + _th;
xpos = vBorder; ypos = vBorder; xpos = HBORDER; ypos = VBORDER + _th;
// Snapshot path (save files) // Snapshot path (save files)
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Save path" + ELLIPSIS, kChooseSnapSaveDirCmd); "Save path" + ELLIPSIS, kChooseSnapSaveDirCmd);
wid.push_back(b); wid.push_back(b);
xpos += buttonWidth + 10; xpos += buttonWidth + 8;
mySnapSavePath = new EditTextWidget(this, font, xpos, ypos + 2, mySnapSavePath = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(mySnapSavePath); wid.push_back(mySnapSavePath);
// Snapshot path (load files) // Snapshot path (load files)
xpos = vBorder; ypos += buttonHeight + 3; xpos = HBORDER; ypos += buttonHeight + V_GAP;
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Load path" + ELLIPSIS, kChooseSnapLoadDirCmd); "Load path" + ELLIPSIS, kChooseSnapLoadDirCmd);
wid.push_back(b); wid.push_back(b);
xpos += buttonWidth + 10; xpos += buttonWidth + 8;
mySnapLoadPath = new EditTextWidget(this, font, xpos, ypos + 2, mySnapLoadPath = new EditTextWidget(this, font, xpos, ypos + 1,
_w - xpos - 10, lineHeight, ""); _w - xpos - HBORDER, lineHeight, "");
wid.push_back(mySnapLoadPath); wid.push_back(mySnapLoadPath);
// Snapshot naming // Snapshot naming
lwidth = font.getStringWidth("Continuous snapshot interval "); xpos = HBORDER; ypos += buttonHeight + V_GAP * 4;
fwidth = font.getStringWidth("internal database"); fwidth = font.getStringWidth("10 seconds");
VariantList items;
VarList::push_back(items, "actual ROM name", "rom");
VarList::push_back(items, "internal database", "int");
xpos = vBorder+10; ypos += buttonHeight + 8;
mySnapName =
new PopUpWidget(this, font, xpos, ypos, fwidth, lineHeight, items,
"Save snapshots according to ", lwidth);
wid.push_back(mySnapName);
// Snapshot interval (continuous mode) // Snapshot interval (continuous mode)
items.clear(); mySnapInterval = new SliderWidget(this, font, xpos, ypos,
VarList::push_back(items, "1 second", "1"); "Continuous snapshot interval ", 0, kSnapshotInterval,
VarList::push_back(items, "2 seconds", "2"); font.getStringWidth("10 seconds"));
VarList::push_back(items, "3 seconds", "3"); mySnapInterval->setMinValue(1);
VarList::push_back(items, "4 seconds", "4"); mySnapInterval->setMaxValue(10);
VarList::push_back(items, "5 seconds", "5");
VarList::push_back(items, "6 seconds", "6");
VarList::push_back(items, "7 seconds", "7");
VarList::push_back(items, "8 seconds", "8");
VarList::push_back(items, "9 seconds", "9");
VarList::push_back(items, "10 seconds", "10");
ypos += buttonHeight;
mySnapInterval =
new PopUpWidget(this, font, xpos, ypos, fwidth, lineHeight, items,
"Continuous snapshot interval ", lwidth);
wid.push_back(mySnapInterval); wid.push_back(mySnapInterval);
// Booleans for saving snapshots // Booleans for saving snapshots
fwidth = font.getStringWidth("When saving snapshots:"); fwidth = font.getStringWidth("When saving snapshots:");
xpos = vBorder; ypos += buttonHeight + 5; xpos = HBORDER; ypos += lineHeight + V_GAP * 3;
new StaticTextWidget(this, font, xpos, ypos, fwidth, lineHeight, new StaticTextWidget(this, font, xpos, ypos, fwidth, lineHeight,
"When saving snapshots:", TextAlign::Left); "When saving snapshots:", TextAlign::Left);
// Snapshot single or multiple saves // Snapshot single or multiple saves
xpos += 30; ypos += lineHeight + 3; xpos += INDENT; ypos += lineHeight + V_GAP;
mySnapSingle = new CheckboxWidget(this, font, xpos, ypos, mySnapName = new CheckboxWidget(this, font, xpos, ypos, "Use actual ROM name");
"Overwrite existing files"); wid.push_back(mySnapName);
ypos += lineHeight + V_GAP;
mySnapSingle = new CheckboxWidget(this, font, xpos, ypos, "Overwrite existing files");
wid.push_back(mySnapSingle); wid.push_back(mySnapSingle);
// Snapshot in 1x mode (ignore scaling) // Snapshot in 1x mode (ignore scaling)
ypos += mySnapSingle->getHeight() + 4; ypos += lineHeight + V_GAP;
mySnap1x = new CheckboxWidget(this, font, xpos, ypos, mySnap1x = new CheckboxWidget(this, font, xpos, ypos,
"Ignore scaling (1x mode)"); "Ignore scaling (1x mode)");
wid.push_back(mySnap1x); wid.push_back(mySnap1x);
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, addDefaultsOKCancelBGroup(wid, font);
font.getStringWidth("Defaults") + 20, buttonHeight,
"Defaults", GuiObject::kDefaultsCmd);
wid.push_back(b);
addOKCancelBGroup(wid, font);
addToFocusList(wid); addToFocusList(wid);
} }
@ -134,8 +117,8 @@ void SnapshotDialog::loadConfig()
const Settings& settings = instance().settings(); const Settings& settings = instance().settings();
mySnapSavePath->setText(settings.getString("snapsavedir")); mySnapSavePath->setText(settings.getString("snapsavedir"));
mySnapLoadPath->setText(settings.getString("snaploaddir")); mySnapLoadPath->setText(settings.getString("snaploaddir"));
mySnapName->setSelected(instance().settings().getString("snapname"), "int"); mySnapInterval->setValue(instance().settings().getInt("ssinterval"));
mySnapInterval->setSelected(instance().settings().getString("ssinterval"), "2"); mySnapName->setState(instance().settings().getString("snapname") == "rom");
mySnapSingle->setState(settings.getBool("sssingle")); mySnapSingle->setState(settings.getBool("sssingle"));
mySnap1x->setState(settings.getBool("ss1x")); mySnap1x->setState(settings.getBool("ss1x"));
} }
@ -145,12 +128,10 @@ void SnapshotDialog::saveConfig()
{ {
instance().settings().setValue("snapsavedir", mySnapSavePath->getText()); instance().settings().setValue("snapsavedir", mySnapSavePath->getText());
instance().settings().setValue("snaploaddir", mySnapLoadPath->getText()); instance().settings().setValue("snaploaddir", mySnapLoadPath->getText());
instance().settings().setValue("snapname", instance().settings().setValue("ssinterval", mySnapInterval->getValue());
mySnapName->getSelectedTag().toString()); instance().settings().setValue("snapname", mySnapName->getState() ? "rom" : "int");
instance().settings().setValue("sssingle", mySnapSingle->getState()); instance().settings().setValue("sssingle", mySnapSingle->getState());
instance().settings().setValue("ss1x", mySnap1x->getState()); instance().settings().setValue("ss1x", mySnap1x->getState());
instance().settings().setValue("ssinterval",
mySnapInterval->getSelectedTag().toString());
// Flush changes to disk and inform the OSystem // Flush changes to disk and inform the OSystem
instance().saveConfig(); instance().saveConfig();
@ -162,10 +143,10 @@ void SnapshotDialog::setDefaults()
{ {
mySnapSavePath->setText(instance().defaultSaveDir()); mySnapSavePath->setText(instance().defaultSaveDir());
mySnapLoadPath->setText(instance().defaultLoadDir()); mySnapLoadPath->setText(instance().defaultLoadDir());
mySnapInterval->setValue(2);
mySnapName->setState(false);
mySnapSingle->setState(false); mySnapSingle->setState(false);
mySnap1x->setState(false); mySnap1x->setState(false);
mySnapInterval->setSelected("2", "2");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -186,16 +167,16 @@ void SnapshotDialog::handleCommand(CommandSender* sender, int cmd,
case kChooseSnapSaveDirCmd: case kChooseSnapSaveDirCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select snapshot save directory");
myBrowser->show("Select snapshot save directory", mySnapSavePath->getText(), myBrowser->show(mySnapSavePath->getText(),
BrowserDialog::Directories, kSnapSaveDirChosenCmd); BrowserDialog::Directories, kSnapSaveDirChosenCmd);
break; break;
case kChooseSnapLoadDirCmd: case kChooseSnapLoadDirCmd:
// This dialog is resizable under certain conditions, so we need // This dialog is resizable under certain conditions, so we need
// to re-create it as necessary // to re-create it as necessary
createBrowser(); createBrowser("Select snapshot load directory");
myBrowser->show("Select snapshot load directory", mySnapLoadPath->getText(), myBrowser->show(mySnapLoadPath->getText(),
BrowserDialog::Directories, kSnapLoadDirChosenCmd); BrowserDialog::Directories, kSnapLoadDirChosenCmd);
break; break;
@ -207,6 +188,13 @@ void SnapshotDialog::handleCommand(CommandSender* sender, int cmd,
mySnapLoadPath->setText(myBrowser->getResult().getShortPath()); mySnapLoadPath->setText(myBrowser->getResult().getShortPath());
break; break;
case kSnapshotInterval:
if(mySnapInterval->getValue() == 1)
mySnapInterval->setValueUnit(" second");
else
mySnapInterval->setValueUnit(" seconds");
break;
default: default:
Dialog::handleCommand(sender, cmd, data, 0); Dialog::handleCommand(sender, cmd, data, 0);
break; break;
@ -214,7 +202,7 @@ void SnapshotDialog::handleCommand(CommandSender* sender, int cmd,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SnapshotDialog::createBrowser() void SnapshotDialog::createBrowser(const string& title)
{ {
uInt32 w = 0, h = 0; uInt32 w = 0, h = 0;
getResizableBounds(w, h); getResizableBounds(w, h);
@ -222,5 +210,7 @@ void SnapshotDialog::createBrowser()
// Create file browser dialog // Create file browser dialog
if(!myBrowser || uInt32(myBrowser->getWidth()) != w || if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
uInt32(myBrowser->getHeight()) != h) uInt32(myBrowser->getHeight()) != h)
myBrowser = make_unique<BrowserDialog>(this, myFont, w, h); myBrowser = make_unique<BrowserDialog>(this, myFont, w, h, title);
else
myBrowser->setTitle(title);
} }

View File

@ -22,7 +22,6 @@ class OSystem;
class GuiObject; class GuiObject;
class DialogContainer; class DialogContainer;
class CheckboxWidget; class CheckboxWidget;
class PopUpWidget;
class EditTextWidget; class EditTextWidget;
class SliderWidget; class SliderWidget;
class StaticTextWidget; class StaticTextWidget;
@ -44,14 +43,15 @@ class SnapshotDialog : public Dialog
void setDefaults() override; void setDefaults() override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
void createBrowser(); void createBrowser(const string& title);
private: private:
enum { enum {
kChooseSnapSaveDirCmd = 'LOss', // snapshot dir (save files) kChooseSnapSaveDirCmd = 'LOss', // snapshot dir (save files)
kChooseSnapLoadDirCmd = 'LOsl', // snapshot dir (load files) kChooseSnapLoadDirCmd = 'LOsl', // snapshot dir (load files)
kSnapSaveDirChosenCmd = 'snsc', // snap chosen (save files) kSnapSaveDirChosenCmd = 'snsc', // snap chosen (save files)
kSnapLoadDirChosenCmd = 'snlc' // snap chosen (load files) kSnapLoadDirChosenCmd = 'snlc', // snap chosen (load files)
kSnapshotInterval = 'SnIn' // snap chosen (load files)
}; };
const GUI::Font& myFont; const GUI::Font& myFont;
@ -60,8 +60,8 @@ class SnapshotDialog : public Dialog
EditTextWidget* mySnapSavePath; EditTextWidget* mySnapSavePath;
EditTextWidget* mySnapLoadPath; EditTextWidget* mySnapLoadPath;
PopUpWidget* mySnapName; CheckboxWidget* mySnapName;
PopUpWidget* mySnapInterval; SliderWidget* mySnapInterval;
CheckboxWidget* mySnapSingle; CheckboxWidget* mySnapSingle;
CheckboxWidget* mySnap1x; CheckboxWidget* mySnap1x;

View File

@ -30,7 +30,7 @@
size: 95 size: 95
ascent: 8 ascent: 8
descent: 2 descent: 2
first char: 32 (0x20) first char: 29 (0x1d)
last char: 126 (0x7e) last char: 126 (0x7e)
default char: 32 (0x20) default char: 32 (0x20)
proportional: no proportional: no
@ -42,6 +42,90 @@ namespace GUI {
// Font character bitmap data. // Font character bitmap data.
static const uInt16 stella_font_bits[] = { static const uInt16 stella_font_bits[] = {
/* Character 29 (0x1d):
width 6
bbx ( 6, 10, 0, -2 )
+------+
| |
| |
| |
| |
| |
| |
| |
|* * * |
| |
| |
+------+
*/
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0b1010100000000000,
0x0000,
0x0000,
/* Character 30 (0x1e):
width 6
bbx ( 6, 10, 0, -2 )
+------+
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+------+
*/
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
/* Character 31 (0x1f):
width 6
bbx ( 6, 10, 0, -2 )
+------+
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+------+
*/
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
/* Character 32 (0x20): /* Character 32 (0x20):
width 6 width 6
bbx ( 6, 10, 0, -2 ) bbx ( 6, 10, 0, -2 )
@ -445,9 +529,9 @@ static const uInt16 stella_font_bits[] = {
| | | |
| | | |
| | | |
| * | | |
| *** | | ** |
| * | | |
| | | |
+------+ +------+
*/ */
@ -457,9 +541,9 @@ static const uInt16 stella_font_bits[] = {
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x2000, 0x0000,
0x7000, 0x6000,
0x2000, 0x0000,
0x0000, 0x0000,
/* Character 47 (0x2f): /* Character 47 (0x2f):
@ -777,25 +861,25 @@ static const uInt16 stella_font_bits[] = {
+------+ +------+
| | | |
| | | |
| * |
| *** |
| * |
| | | |
| * | | ** |
| *** | | |
| * | | |
| |
| ** |
| |
| | | |
+------+ +------+
*/ */
0x0000, 0x0000,
0x0000, 0x0000,
0x2000,
0x7000,
0x2000,
0x0000, 0x0000,
0x2000, 0x6000,
0x7000, 0x0000,
0x2000, 0x0000,
0x0000,
0x6000,
0x0000,
0x0000, 0x0000,
/* Character 59 (0x3b): /* Character 59 (0x3b):
@ -805,9 +889,9 @@ static const uInt16 stella_font_bits[] = {
+------+ +------+
| | | |
| | | |
| * | | |
| *** | | ** |
| * | | |
| | | |
| ** | | ** |
| * | | * |
@ -817,9 +901,9 @@ static const uInt16 stella_font_bits[] = {
*/ */
0x0000, 0x0000,
0x0000, 0x0000,
0x2000, 0x0000,
0x7000, 0x3000,
0x2000, 0x0000,
0x0000, 0x0000,
0x3000, 0x3000,
0x2000, 0x2000,
@ -2710,8 +2794,8 @@ static const FontDesc stellaDesc = {
10, 10,
6, 10, 0, -2, 6, 10, 0, -2,
8, 8,
32, 29,
95, 98,
stella_font_bits, stella_font_bits,
nullptr, /* no encode table*/ nullptr, /* no encode table*/
nullptr, /* fixed width*/ nullptr, /* fixed width*/

View File

@ -30,9 +30,9 @@
size: 95 size: 95
ascent: 14 ascent: 14
descent: 4 descent: 4
first char: 30 (0x1e) first char: 29 (0x1d)
last char: 126 (0x7e) last char: 126 (0x7e)
default char: 30 (0x1e) default char: 32 (0x20)
proportional: no proportional: no
Public domain font. Share and enjoy. Public domain font. Share and enjoy.
*/ */

View File

@ -39,6 +39,20 @@ void StringListWidget::setList(const StringList& list)
ListWidget::recalc(); ListWidget::recalc();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void StringListWidget::handleMouseEntered()
{
setFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void StringListWidget::handleMouseLeft()
{
clearFlags(WIDGET_HILITED);
setDirty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void StringListWidget::drawWidget(bool hilite) void StringListWidget::drawWidget(bool hilite)
{ {
@ -46,9 +60,7 @@ void StringListWidget::drawWidget(bool hilite)
int i, pos, len = int(_list.size()); int i, pos, len = int(_list.size());
// Draw a thin frame around the list. // Draw a thin frame around the list.
s.hLine(_x, _y, _x + _w - 1, kColor); s.frameRect(_x, _y, _w + 1, _h, hilite && _hilite ? kWidColorHi : kColor);
s.hLine(_x, _y + _h - 1, _x + _w - 1, kShadowColor);
s.vLine(_x, _y, _y + _h - 1, kColor);
// Draw the list items // Draw the list items
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++) for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
@ -65,7 +77,7 @@ void StringListWidget::drawWidget(bool hilite)
textColor = kTextColorInv; textColor = kTextColorInv;
} }
else else
s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kTextColorHi); s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kWidColorHi);
} }
GUI::Rect r(getEditRect()); GUI::Rect r(getEditRect());

View File

@ -32,6 +32,8 @@ class StringListWidget : public ListWidget
bool wantsFocus() const override { return true; } bool wantsFocus() const override { return true; }
protected: protected:
void handleMouseEntered() override;
void handleMouseLeft() override;
void drawWidget(bool hilite) override; void drawWidget(bool hilite) override;
GUI::Rect getEditRect() const override; GUI::Rect getEditRect() const override;

View File

@ -253,29 +253,6 @@ void TabWidget::loadConfig()
updateActiveTab(); updateActiveTab();
} }
#ifndef FLAT_UI
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TabWidget::box(int x, int y, int width, int height,
uInt32 colorA, uInt32 colorB, bool omitBottom)
{
//cerr << "TabWidget::box\n";
FBSurface& s = _boss->dialog().surface();
s.hLine(x + 1, y, x + width - 2, colorA);
s.hLine(x, y + 1, x + width - 1, colorA);
s.vLine(x, y + 1, y + height - (omitBottom ? 1 : 2), colorA);
s.vLine(x + 1, y, y + height - (omitBottom ? 2 : 1), colorA);
if (!omitBottom)
{
s.hLine(x + 1, y + height - 2, x + width - 1, colorB);
s.hLine(x + 1, y + height - 1, x + width - 2, colorB);
}
s.vLine(x + width - 1, y + 1, y + height - (omitBottom ? 1 : 2), colorB);
s.vLine(x + width - 2, y + 1, y + height - (omitBottom ? 2 : 1), colorB);
}
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TabWidget::drawWidget(bool hilite) void TabWidget::drawWidget(bool hilite)
{ {
@ -291,25 +268,11 @@ void TabWidget::drawWidget(bool hilite)
const int left2 = right1 + _tabWidth; const int left2 = right1 + _tabWidth;
const int right2 = _x + _w - 2; const int right2 = _x + _w - 2;
#ifndef FLAT_UI
// Draw horizontal line
s.hLine(left1, _y + _tabHeight - 2, right1, kShadowColor);
s.hLine(left2, _y + _tabHeight - 2, right2, kShadowColor);
#endif
// Iterate over all tabs and draw them // Iterate over all tabs and draw them
int i, x = _x + kTabLeftOffset; int i, x = _x + kTabLeftOffset;
for (i = 0; i < int(_tabs.size()); ++i) for (i = 0; i < int(_tabs.size()); ++i)
{ {
uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor; uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor;
#ifndef FLAT_UI
uInt32 boxcolor = (i == _activeTab) ? kColor : kShadowColor;
int yOffset = (i == _activeTab) ? 0 : 2;
box(x, _y + yOffset, _tabWidth, _tabHeight - yOffset, boxcolor, boxcolor, (i == _activeTab));
s.drawString(_font, _tabs[i].title, x + kTabPadding,
_y + yOffset / 2 + (_tabHeight - _fontHeight - 1),
_tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center);
#else
int yOffset = (i == _activeTab) ? 0 : 1; int yOffset = (i == _activeTab) ? 0 : 1;
s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1, (i == _activeTab) s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1, (i == _activeTab)
? kDlgColor : kBGColorHi); // ? kWidColor : kDlgColor ? kDlgColor : kBGColorHi); // ? kWidColor : kDlgColor
@ -323,23 +286,13 @@ void TabWidget::drawWidget(bool hilite)
} }
else else
s.hLine(x, _y + _tabHeight, x + _tabWidth, kWidColor); s.hLine(x, _y + _tabHeight, x + _tabWidth, kWidColor);
#endif
x += _tabWidth + kTabSpacing; x += _tabWidth + kTabSpacing;
} }
#ifndef FLAT_UI
// Draw a frame around the widget area (belows the tabs)
s.hLine(left1, _y + _tabHeight - 1, right1, kColor);
s.hLine(left2, _y + _tabHeight - 1, right2, kColor);
s.hLine(_x+1, _y + _h - 2, _x + _w - 2, kShadowColor);
s.hLine(_x+1, _y + _h - 1, _x + _w - 2, kColor);
s.vLine(_x + _w - 2, _y + _tabHeight - 1, _y + _h - 2, kColor);
s.vLine(_x + _w - 1, _y + _tabHeight - 1, _y + _h - 2, kShadowColor);
#else
// fill empty right space // fill empty right space
s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, kWidColor); s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, kWidColor);
s.hLine(_x, _y + _h - 1, _x + _w - 1, kBGColorLo); s.hLine(_x, _y + _h - 1, _x + _w - 1, kBGColorLo);
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -90,22 +90,12 @@ class TabWidget : public Widget, public CommandSender
bool _firstTime; bool _firstTime;
enum { enum {
#ifndef FLAT_UI
kTabLeftOffset = 4,
kTabSpacing = 2,
kTabPadding = 3
#else
kTabLeftOffset = 0, kTabLeftOffset = 0,
kTabSpacing = 1, kTabSpacing = 1,
kTabPadding = 4 kTabPadding = 4
#endif
}; };
private: private:
#ifndef FLAT_UI
void box(int x, int y, int width, int height,
uInt32 colorA, uInt32 colorB, bool omitBottom);
#endif
void updateActiveTab(); void updateActiveTab();
private: private:

232
src/gui/TimeLineWidget.cxx Normal file
View File

@ -0,0 +1,232 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "bspf.hxx"
#include "Command.hxx"
#include "Dialog.hxx"
#include "Font.hxx"
#include "FBSurface.hxx"
#include "GuiObject.hxx"
#include "OSystem.hxx"
#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)
: ButtonWidget(boss, font, x, y, w, h, label, cmd),
_value(0),
_stepValue__(1),
_valueMin(0),
_valueMax(100),
_isDragging(false),
_labelWidth(labelWidth)
{
_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE;
_bgcolor = kDlgColor;
_bgcolorhi = kDlgColor;
if(!_label.empty() && _labelWidth == 0)
_labelWidth = _font.getStringWidth(_label);
_w = w + _labelWidth;
_stepValue.reserve(100);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::setValue(int value)
{
if(value < _valueMin) value = _valueMin;
else if(value > _valueMax) value = _valueMax;
if(value != _value)
{
_value = value;
setDirty();
sendCommand(_cmd, _value, _id);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::setMinValue(int value)
{
_valueMin = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::setMaxValue(int value)
{
_valueMax = 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());
// 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 - 4);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
{
if(isEnabled() && b == MouseButton::LEFT)
{
_isDragging = true;
handleMouseMoved(x, y);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
{
if(isEnabled() && _isDragging)
sendCommand(_cmd, _value, _id);
_isDragging = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::handleMouseWheel(int x, int y, int direction)
{
if(isEnabled())
{
if(direction < 0)
handleEvent(Event::UIUp);
else if(direction > 0)
handleEvent(Event::UIDown);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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)
{
FBSurface& s = _boss->dialog().surface();
#ifndef FLAT_UI
// Draw the label, if any
if(_labelWidth > 0)
s.drawString(_font, _label, _x, _y + 2, _labelWidth,
isEnabled() ? kTextColor : kColor, TextAlign::Right);
// Draw the box
s.box(_x + _labelWidth, _y, _w - _labelWidth, _h, kColor, kShadowColor);
// Fill the box
s.fillRect(_x + _labelWidth + 2, _y + 2, _w - _labelWidth - 4, _h - 4,
!isEnabled() ? kBGColorHi : kWidColor);
// Draw the 'bar'
s.fillRect(_x + _labelWidth + 2, _y + 2, valueToPos(_value), _h - 4,
!isEnabled() ? kColor : hilite ? kSliderColorHi : kSliderColor);
#else
// Draw the label, if any
if(_labelWidth > 0)
s.drawString(_font, _label, _x, _y + 2, _labelWidth,
isEnabled() ? kTextColor : kColor, TextAlign::Left);
// Draw the box
s.frameRect(_x + _labelWidth, _y, _w - _labelWidth, _h, isEnabled() && hilite ? kSliderColorHi : kShadowColor);
// Fill the box
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,
!isEnabled() ? kColor : hilite ? kSliderColorHi : kSliderColor);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int TimeLineWidget::valueToPos(int 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;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int TimeLineWidget::posToValue(int pos)
{
int value = (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin;
// Scale the position to the correct interval (according to step value)
return value - (value % _stepValue__);
}

View File

@ -0,0 +1,73 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef TIMELINE_WIDGET_HXX
#define TIMELINE_WIDGET_HXX
#include "Widget.hxx"
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);
void setValue(int value);
int getValue() const { return _value; }
void setMinValue(int value);
int getMinValue() const { return _valueMin; }
void setMaxValue(int value);
int getMaxValue() const { return _valueMax; }
/**
Steps are not necessarily linear in a timeline, so we need info
on each interval instead.
*/
void setStepValues(const IntArray& steps);
protected:
void handleMouseMoved(int x, int y) override;
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);
protected:
int _value, _stepValue__;
int _valueMin, _valueMax;
bool _isDragging;
int _labelWidth;
IntArray _stepValue;
private:
// Following constructors and assignment operators not supported
TimeLineWidget() = delete;
TimeLineWidget(const TimeLineWidget&) = delete;
TimeLineWidget(TimeLineWidget&&) = delete;
TimeLineWidget& operator=(const TimeLineWidget&) = delete;
TimeLineWidget& operator=(TimeLineWidget&&) = delete;
};
#endif

Some files were not shown because too many files have changed in this diff Show More