mirror of https://github.com/stella-emu/stella.git
Merge branch 'master' into feature/precise-audio
This commit is contained in:
commit
5c1bd83904
|
@ -1,3 +1,12 @@
|
|||
5.1 to 5.2: (MMM d, 2018)
|
||||
|
||||
* Extra functionality for Time Machine dialog (start/stop recording;
|
||||
minor fixes; TODO button and initial key repeats...)
|
||||
|
||||
* Fixes for collision corner cases (during HBlank)
|
||||
|
||||
* UI modernization (new widget look, dialog titles added, dialogs refactored)
|
||||
|
||||
5.0.2 to 5.1: (February 4, 2018)
|
||||
|
||||
* Added "Time Machine" mode, which automatically creates save states
|
||||
|
|
|
@ -44,20 +44,11 @@ class FixedStack
|
|||
bool full() const { return _size >= CAPACITY; }
|
||||
|
||||
T top() const { return _stack[_size - 1]; }
|
||||
T get(uInt32 pos) { return _stack[pos]; };
|
||||
T get(uInt32 pos) { return _stack[pos]; }
|
||||
void push(const T& x) { _stack[_size++] = x; }
|
||||
T pop() { return std::move(_stack[--_size]); }
|
||||
uInt32 size() const { return _size; }
|
||||
|
||||
void replace(const T& oldItem, const T& newItem) {
|
||||
for(uInt32 i = 0; i < _size; ++i) {
|
||||
if(_stack[i] == oldItem) {
|
||||
_stack[i] = newItem;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the given function to every item in the stack
|
||||
// We do it this way so the stack API can be preserved,
|
||||
// and no access to individual elements is allowed outside
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef VERSION_HXX
|
||||
#define VERSION_HXX
|
||||
|
||||
#define STELLA_VERSION "5.1"
|
||||
#define STELLA_VERSION "5.2_pre"
|
||||
#define STELLA_BUILD "4138"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,8 +26,7 @@ PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font,
|
|||
bool leftport = isLeftPort();
|
||||
const string& label = getHeader();
|
||||
|
||||
const int fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight(),
|
||||
const int fontHeight = font.getFontHeight(),
|
||||
lineHeight = font.getLineHeight();
|
||||
int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Paddles)");
|
||||
|
||||
|
|
|
@ -301,19 +301,19 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
|||
{
|
||||
case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states
|
||||
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, false);
|
||||
return;
|
||||
break;
|
||||
|
||||
case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states
|
||||
enterTimeMachineMenuMode((StellaModTest::isShift(mod) && state) ? 10 : 1, true);
|
||||
return;
|
||||
break;
|
||||
|
||||
case KBDK_DOWN: // Alt-down rewinds to start of list
|
||||
enterTimeMachineMenuMode(1000, false);
|
||||
return;
|
||||
break;
|
||||
|
||||
case KBDK_UP: // Alt-up rewinds to end of list
|
||||
enterTimeMachineMenuMode(1000, true);
|
||||
return;
|
||||
break;
|
||||
|
||||
// These can work in pause mode too
|
||||
case KBDK_EQUALS:
|
||||
|
@ -2151,13 +2151,11 @@ void EventHandler::enterTimeMachineMenuMode(uInt32 numWinds, bool unwind)
|
|||
// add one extra state if we are in Time Machine mode
|
||||
// TODO: maybe remove this state if we leave the menu at this new state
|
||||
myOSystem.state().addExtraState("enter Time Machine dialog"); // force new state
|
||||
if(numWinds)
|
||||
myOSystem.state().windStates(numWinds, unwind);
|
||||
|
||||
if(numWinds)
|
||||
myOSystem.state().windStates(numWinds, unwind);
|
||||
// hande winds and display wind message (numWinds != 0) in time machine dialog
|
||||
myOSystem.timeMachine().setEnterWinds(unwind ? numWinds : -numWinds);
|
||||
|
||||
// TODO: display last wind message (numWinds != 0) in time machine dialog
|
||||
enterMenuMode(EventHandlerState::TIMEMACHINE);
|
||||
}
|
||||
|
||||
|
|
|
@ -268,14 +268,12 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
|||
break;
|
||||
|
||||
case FrameStyle::Dashed:
|
||||
uInt32 i, skip, lwidth = 1;
|
||||
|
||||
for(i = x; i < x + w; i += 2)
|
||||
for(uInt32 i = x; i < x + w; i += 2)
|
||||
{
|
||||
hLine(i, y, i, color);
|
||||
hLine(i, y + h - 1, i, color);
|
||||
}
|
||||
for(i = y; i < y + h; i += 2)
|
||||
for(uInt32 i = y; i < y + h; i += 2)
|
||||
{
|
||||
vLine(x, i, i, color);
|
||||
vLine(x + w - 1, i, i, color);
|
||||
|
|
|
@ -385,9 +385,8 @@ void FrameBuffer::drawFrameStats()
|
|||
int xPos = XPOS;
|
||||
|
||||
myStatsMsg.surface->invalidate();
|
||||
string bsinfo = info.BankSwitch +
|
||||
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "");
|
||||
// draw shadowed text
|
||||
|
||||
// draw scanlines
|
||||
color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ?
|
||||
uInt32(kDbgColorRed) : myStatsMsg.color;
|
||||
std::snprintf(msg, 30, "%3u", myOSystem.console().tia().scanlinesLastFrame());
|
||||
|
@ -395,16 +394,20 @@ void FrameBuffer::drawFrameStats()
|
|||
myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor);
|
||||
xPos += font().getStringWidth(msg);
|
||||
|
||||
// draw frequency
|
||||
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);
|
||||
|
||||
std::snprintf(msg, 30, " @ %5.2ffps", myOSystem.console().getFramerate());
|
||||
|
||||
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
// draw bankswitching type
|
||||
string bsinfo = info.BankSwitch +
|
||||
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "");
|
||||
myStatsMsg.surface->drawString(font(), bsinfo, XPOS, YPOS + font().getFontHeight(),
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
|
@ -1016,7 +1019,7 @@ uInt32 FrameBuffer::ourGUIColors[3][kNumColors-256] = {
|
|||
0x20a020, 0x00ff00, // scrollbar
|
||||
0x20a020, 0x00ff00, 0x404040, 0x686868, 0x404040, // slider
|
||||
0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000, // debugger
|
||||
0x20a020, 0x20a020, 0x000000, 0x686868, 0x404040 // other
|
||||
0x00ff00, 0x20a020, 0x000000, 0x686868, 0x404040 // other
|
||||
},
|
||||
// Light
|
||||
{ 0x808080, 0x000000, 0xc0c0c0, 0xe1e1e1, 0x333333, // base
|
||||
|
|
|
@ -213,6 +213,56 @@ void OSystem::setConfigPaths()
|
|||
mySettings->setValue("propsfile", node.getShortPath());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PropertiesSet& OSystem::propSet(const string& md5)
|
||||
{
|
||||
FilesystemNode node = FilesystemNode();
|
||||
|
||||
return propSet(md5, node);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PropertiesSet& OSystem::propSet(const string& md5, const FilesystemNode& node)
|
||||
{
|
||||
if(md5 == EmptyString)
|
||||
return *myPropSet;
|
||||
else if(md5 == myGamePropSetMD5)
|
||||
return *myGamePropSet;
|
||||
else if (!node.exists())
|
||||
return *myPropSet;
|
||||
|
||||
// Get a valid set of game specific properties
|
||||
Properties props;
|
||||
string path = myBaseDir + node.getNameWithExt(".pro");
|
||||
|
||||
// Create a properties set based on ROM name
|
||||
FilesystemNode propNode = FilesystemNode(path);
|
||||
myGamePropertiesFile = propNode.getPath();
|
||||
|
||||
myGamePropSet = make_unique<PropertiesSet>(myGamePropertiesFile);
|
||||
|
||||
// Check if game specific property file exists and has matching md5
|
||||
if(myGamePropSet->size() && myGamePropSet->getMD5(md5, props))
|
||||
{
|
||||
myGamePropSetMD5 = md5;
|
||||
return *myGamePropSet;
|
||||
}
|
||||
else
|
||||
{
|
||||
myGamePropSetMD5 = "";
|
||||
return *myPropSet;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void OSystem::saveGamePropSet(const string& md5)
|
||||
{
|
||||
if(myGamePropSet->size() && md5 == myGamePropSetMD5)
|
||||
{
|
||||
myGamePropSet->save(myGamePropertiesFile);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void OSystem::setBaseDir(const string& basedir)
|
||||
{
|
||||
|
@ -428,8 +478,7 @@ void OSystem::logMessage(const string& message, uInt8 level)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
unique_ptr<Console>
|
||||
OSystem::openConsole(const FilesystemNode& romfile, string& md5)
|
||||
unique_ptr<Console> OSystem::openConsole(const FilesystemNode& romfile, string& md5)
|
||||
{
|
||||
unique_ptr<Console> console;
|
||||
|
||||
|
@ -441,8 +490,15 @@ OSystem::openConsole(const FilesystemNode& romfile, string& md5)
|
|||
// Get a valid set of properties, including any entered on the commandline
|
||||
// For initial creation of the Cart, we're only concerned with the BS type
|
||||
Properties props;
|
||||
myPropSet->getMD5(md5, props);
|
||||
|
||||
// Load and use game specific props if existing
|
||||
FilesystemNode node = FilesystemNode(romfile);
|
||||
|
||||
string path = myBaseDir + node.getNameWithExt(".pro");
|
||||
PropertiesSet& propset = propSet(md5, romfile);
|
||||
propset.getMD5(md5, props);
|
||||
|
||||
// Local helper method
|
||||
auto CMDLINE_PROPS_UPDATE = [&](const string& name, PropertyType prop)
|
||||
{
|
||||
const string& s = mySettings->getString(name);
|
||||
|
@ -462,12 +518,12 @@ OSystem::openConsole(const FilesystemNode& romfile, string& md5)
|
|||
// and that the md5 (and hence the cart) has changed
|
||||
if(props.get(Cartridge_MD5) != cartmd5)
|
||||
{
|
||||
if(!myPropSet->getMD5(cartmd5, props))
|
||||
if(!propset.getMD5(cartmd5, props))
|
||||
{
|
||||
// Cart md5 wasn't found, so we create a new props for it
|
||||
props.set(Cartridge_MD5, cartmd5);
|
||||
props.set(Cartridge_Name, props.get(Cartridge_Name)+cart->multiCartID());
|
||||
myPropSet->insert(props, false);
|
||||
propset.insert(props, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,13 @@ class OSystem
|
|||
|
||||
@return The properties set object
|
||||
*/
|
||||
PropertiesSet& propSet() const { return *myPropSet; }
|
||||
PropertiesSet& propSet(const string& md5 = EmptyString);
|
||||
PropertiesSet& propSet(const string& md5, const FilesystemNode& node);
|
||||
|
||||
/**
|
||||
Save the game specific property file.
|
||||
*/
|
||||
void saveGamePropSet(const string& md5);
|
||||
|
||||
/**
|
||||
Get the console of the system. The console won't always exist,
|
||||
|
@ -427,6 +433,12 @@ class OSystem
|
|||
// Pointer to the PropertiesSet object
|
||||
unique_ptr<PropertiesSet> myPropSet;
|
||||
|
||||
// Pointer to the game's PropertiesSet object
|
||||
unique_ptr<PropertiesSet> myGamePropSet;
|
||||
|
||||
// MD5 of the currently loaded game PropertiesSet object
|
||||
string myGamePropSetMD5;
|
||||
|
||||
// Pointer to the (currently defined) Console object
|
||||
unique_ptr<Console> myConsole;
|
||||
|
||||
|
@ -480,6 +492,7 @@ class OSystem
|
|||
string myConfigFile;
|
||||
string myPaletteFile;
|
||||
string myPropertiesFile;
|
||||
string myGamePropertiesFile;
|
||||
|
||||
FilesystemNode myRomFile;
|
||||
string myRomMD5;
|
||||
|
|
|
@ -112,6 +112,11 @@ class PropertiesSet
|
|||
*/
|
||||
void print() const;
|
||||
|
||||
/**
|
||||
Return the size of the myExternalProps list
|
||||
*/
|
||||
uInt32 size() { return myExternalProps.size(); }
|
||||
|
||||
private:
|
||||
using PropsList = std::map<string, Properties>;
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ void Ball::reset()
|
|||
myIsEnabledNew = false;
|
||||
myIsEnabled = false;
|
||||
myIsDelaying = false;
|
||||
myIsVisible = false;
|
||||
myHmmClocks = 0;
|
||||
myCounter = 0;
|
||||
myIsMoving = false;
|
||||
|
@ -49,8 +50,7 @@ void Ball::reset()
|
|||
myIsRendering = false;
|
||||
myDebugEnabled = false;
|
||||
myRenderCounter = 0;
|
||||
|
||||
updateEnabled();
|
||||
myIsEnabled = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -62,7 +62,10 @@ void Ball::enabl(uInt8 value)
|
|||
|
||||
if (myIsEnabledNew != enabledNewOldValue && !myIsDelaying) {
|
||||
myTIA->flushLineCache();
|
||||
|
||||
updateEnabled();
|
||||
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
myTIA->updateCollision();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,9 +176,8 @@ bool Ball::movementTick(uInt32 clock, bool apply)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::tick(bool isReceivingMclock)
|
||||
{
|
||||
collision = (myIsRendering && myRenderCounter >= 0 && myIsEnabled) ?
|
||||
myCollisionMaskEnabled :
|
||||
myCollisionMaskDisabled;
|
||||
myIsVisible = myIsRendering && myRenderCounter >= 0;
|
||||
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
|
||||
bool starfieldEffect = myIsMoving && isReceivingMclock;
|
||||
|
||||
|
@ -207,6 +209,13 @@ void Ball::tick(bool isReceivingMclock)
|
|||
myCounter = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::nextLine()
|
||||
{
|
||||
myIsVisible = myIsRendering && myRenderCounter >= 0;
|
||||
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::setENABLOld(bool enabled)
|
||||
{
|
||||
|
@ -233,6 +242,9 @@ void Ball::shuffleStatus()
|
|||
void Ball::updateEnabled()
|
||||
{
|
||||
myIsEnabled = !myIsSuppressed && (myIsDelaying ? myIsEnabledOld : myIsEnabledNew);
|
||||
|
||||
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
myTIA->updateCollision();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -293,6 +305,7 @@ bool Ball::save(Serializer& out) const
|
|||
out.putBool(myIsEnabled);
|
||||
out.putBool(myIsSuppressed);
|
||||
out.putBool(myIsDelaying);
|
||||
out.putBool(myIsVisible);
|
||||
|
||||
out.putByte(myHmmClocks);
|
||||
out.putByte(myCounter);
|
||||
|
@ -335,6 +348,7 @@ bool Ball::load(Serializer& in)
|
|||
myIsEnabled = in.getBool();
|
||||
myIsSuppressed = in.getBool();
|
||||
myIsDelaying = in.getBool();
|
||||
myIsVisible = in.getBool();
|
||||
|
||||
myHmmClocks = in.getByte();
|
||||
myCounter = in.getByte();
|
||||
|
|
|
@ -62,6 +62,8 @@ class Ball : public Serializable
|
|||
|
||||
void tick(bool isReceivingMclock = true);
|
||||
|
||||
void nextLine();
|
||||
|
||||
bool isOn() const { return (collision & 0x8000); }
|
||||
uInt8 getColor() const { return myColor; }
|
||||
|
||||
|
@ -105,6 +107,7 @@ class Ball : public Serializable
|
|||
bool myIsEnabled;
|
||||
bool myIsSuppressed;
|
||||
bool myIsDelaying;
|
||||
bool myIsVisible;
|
||||
|
||||
uInt8 myHmmClocks;
|
||||
uInt8 myCounter;
|
||||
|
|
|
@ -47,12 +47,12 @@ void Missile::reset()
|
|||
myWidth = 1;
|
||||
myEffectiveWidth = 1;
|
||||
myIsRendering = false;
|
||||
myIsVisible = false;
|
||||
myRenderCounter = 0;
|
||||
myColor = myObjectColor = myDebugColor = 0;
|
||||
myDebugEnabled = false;
|
||||
collision = myCollisionMaskDisabled;
|
||||
|
||||
updateEnabled();
|
||||
myIsEnabled = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -62,9 +62,11 @@ void Missile::enam(uInt8 value)
|
|||
|
||||
myEnam = (value & 0x02) > 0;
|
||||
|
||||
if (oldEnam != myEnam) myTIA->flushLineCache();
|
||||
if (oldEnam != myEnam) {
|
||||
myTIA->flushLineCache();
|
||||
|
||||
updateEnabled();
|
||||
updateEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -166,41 +168,43 @@ bool Missile::movementTick(uInt8 clock, uInt8 hclock, bool apply)
|
|||
|
||||
if (clock == myHmmClocks) myIsMoving = false;
|
||||
|
||||
if (myIsMoving && apply) tick(hclock);
|
||||
if (myIsMoving && apply) tick(hclock, false);
|
||||
|
||||
return myIsMoving;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Missile::tick(uInt8 hclock)
|
||||
void Missile::tick(uInt8 hclock, bool isReceivingMclock)
|
||||
{
|
||||
const bool render =
|
||||
myIsVisible =
|
||||
myIsRendering &&
|
||||
(myRenderCounter >= 0 || (myIsMoving && myRenderCounter == -1 && myWidth < 4 && ((hclock + 1) % 4 == 3))) &&
|
||||
myIsEnabled;
|
||||
(myRenderCounter >= 0 || (myIsMoving && isReceivingMclock && myRenderCounter == -1 && myWidth < 4 && ((hclock + 1) % 4 == 3)));
|
||||
|
||||
collision = render ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
|
||||
if (myDecodes[myCounter] && !myResmp) {
|
||||
myIsRendering = true;
|
||||
myRenderCounter = Count::renderCounterOffset;
|
||||
} else if (myIsRendering) {
|
||||
|
||||
if (myIsMoving && myRenderCounter == -1) {
|
||||
if (myRenderCounter == -1) {
|
||||
if (myIsMoving && isReceivingMclock) {
|
||||
switch ((hclock + 1) % 4) {
|
||||
case 3:
|
||||
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
|
||||
if (myWidth < 4) myRenderCounter++;
|
||||
break;
|
||||
|
||||
switch ((hclock + 1) % 4) {
|
||||
case 3:
|
||||
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
|
||||
if (myWidth < 4) myRenderCounter++;
|
||||
break;
|
||||
case 2:
|
||||
myEffectiveWidth = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
myEffectiveWidth = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
myEffectiveWidth = myWidth;
|
||||
break;
|
||||
default:
|
||||
myEffectiveWidth = myWidth;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
myEffectiveWidth = myWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,6 +214,13 @@ void Missile::tick(uInt8 hclock)
|
|||
if (++myCounter >= 160) myCounter = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Missile::nextLine()
|
||||
{
|
||||
myIsVisible = myIsRendering && (myRenderCounter >= 0);
|
||||
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Missile::setColor(uInt8 color)
|
||||
{
|
||||
|
@ -246,6 +257,9 @@ void Missile::applyColorLoss()
|
|||
void Missile::updateEnabled()
|
||||
{
|
||||
myIsEnabled = !myIsSuppressed && myEnam && !myResmp;
|
||||
|
||||
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
myTIA->updateCollision();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -308,6 +322,7 @@ bool Missile::save(Serializer& out) const
|
|||
out.putByte(myEffectiveWidth);
|
||||
out.putByte(myLastMovementTick);
|
||||
|
||||
out.putBool(myIsVisible);
|
||||
out.putBool(myIsRendering);
|
||||
out.putByte(myRenderCounter);
|
||||
|
||||
|
@ -350,6 +365,7 @@ bool Missile::load(Serializer& in)
|
|||
myEffectiveWidth = in.getByte();
|
||||
myLastMovementTick = in.getByte();
|
||||
|
||||
myIsVisible = in.getBool();
|
||||
myIsRendering = in.getBool();
|
||||
myRenderCounter = in.getByte();
|
||||
|
||||
|
|
|
@ -50,7 +50,9 @@ class Missile : public Serializable
|
|||
|
||||
bool movementTick(uInt8 clock, uInt8 hclock, bool apply);
|
||||
|
||||
void tick(uInt8 hclock);
|
||||
void tick(uInt8 hclock, bool isReceivingMclock = true);
|
||||
|
||||
void nextLine();
|
||||
|
||||
void setColor(uInt8 color);
|
||||
|
||||
|
@ -103,6 +105,7 @@ class Missile : public Serializable
|
|||
uInt8 myLastMovementTick;
|
||||
|
||||
bool myIsRendering;
|
||||
bool myIsVisible;
|
||||
Int8 myRenderCounter;
|
||||
|
||||
const uInt8* myDecodes;
|
||||
|
|
|
@ -52,9 +52,9 @@ void Player::reset()
|
|||
mySampleCounter = 0;
|
||||
myDividerPending = 0;
|
||||
myDividerChangeCounter = -1;
|
||||
myPattern = 0;
|
||||
|
||||
setDivider(1);
|
||||
updatePattern();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -309,6 +309,15 @@ void Player::tick()
|
|||
if (++myCounter >= 160) myCounter = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Player::nextLine()
|
||||
{
|
||||
if (!myIsRendering || myRenderCounter < myRenderCounterTripPoint)
|
||||
collision = myCollisionMaskDisabled;
|
||||
else
|
||||
collision = (myPattern & (1 << mySampleCounter)) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Player::shufflePatterns()
|
||||
{
|
||||
|
@ -372,6 +381,11 @@ void Player::updatePattern()
|
|||
((myPattern & 0x80) >> 7)
|
||||
);
|
||||
}
|
||||
|
||||
if (myIsRendering && myRenderCounter >= myRenderCounterTripPoint) {
|
||||
collision = (myPattern & (1 << mySampleCounter)) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
myTIA->updateCollision();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -62,6 +62,9 @@ class Player : public Serializable
|
|||
bool movementTick(uInt32 clock, bool apply);
|
||||
|
||||
void tick();
|
||||
|
||||
void nextLine();
|
||||
|
||||
uInt8 getClock() const { return myCounter; }
|
||||
|
||||
bool isOn() const { return (collision & 0x8000); }
|
||||
|
|
|
@ -204,6 +204,12 @@ void Playfield::tick(uInt32 x)
|
|||
collision = currentPixel ? myCollisionMaskEnabled : myCollisionMaskDisabled;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Playfield::nextLine()
|
||||
{
|
||||
collision = myCollisionMaskDisabled;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Playfield::applyColors()
|
||||
{
|
||||
|
|
|
@ -59,6 +59,8 @@ class Playfield : public Serializable
|
|||
|
||||
void tick(uInt32 x);
|
||||
|
||||
void nextLine();
|
||||
|
||||
bool isOn() const { return (collision & 0x8000); }
|
||||
uInt8 getColor() const;
|
||||
|
||||
|
|
|
@ -1273,7 +1273,6 @@ void TIA::nextLine()
|
|||
cloneLastLine();
|
||||
}
|
||||
|
||||
myPlayfield.tick(0);
|
||||
myHctr = 0;
|
||||
|
||||
if (!myMovementInProgress && myLinesSinceChange < 2) myLinesSinceChange++;
|
||||
|
@ -1282,6 +1281,12 @@ void TIA::nextLine()
|
|||
myHctrDelta = 0;
|
||||
|
||||
myFrameManager->nextLine();
|
||||
myMissile0.nextLine();
|
||||
myMissile1.nextLine();
|
||||
myPlayer0.nextLine();
|
||||
myPlayer1.nextLine();
|
||||
myBall.nextLine();
|
||||
myPlayfield.nextLine();
|
||||
|
||||
if (myFrameManager->isRendering() && myFrameManager->getY() == 0) flushLineCache();
|
||||
|
||||
|
|
|
@ -415,6 +415,11 @@ class TIA : public Device
|
|||
*/
|
||||
void flushLineCache();
|
||||
|
||||
/**
|
||||
* Update the collision bitfield.
|
||||
*/
|
||||
void updateCollision();
|
||||
|
||||
/**
|
||||
Create a new delayQueueIterator for the debugger.
|
||||
*/
|
||||
|
@ -511,11 +516,6 @@ class TIA : public Device
|
|||
*/
|
||||
void applyRsync();
|
||||
|
||||
/**
|
||||
* Update the collision bitfield.
|
||||
*/
|
||||
void updateCollision();
|
||||
|
||||
/**
|
||||
* Render the current pixel into the framebuffer.
|
||||
*/
|
||||
|
|
|
@ -42,9 +42,7 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent,
|
|||
const int INDENT = 20;
|
||||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight(),
|
||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
fontHeight = font.getFontHeight();
|
||||
int xpos, ypos;
|
||||
int lwidth = font.getStringWidth("Sample Size (*) "),
|
||||
pwidth = font.getStringWidth("512 bytes");
|
||||
|
|
|
@ -33,10 +33,7 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
|
|||
myComboEvent(Event::NoType)
|
||||
{
|
||||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight(),
|
||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
fontWidth = font.getMaxCharWidth();
|
||||
int xpos, ypos;
|
||||
WidgetArray wid;
|
||||
|
||||
|
|
|
@ -27,13 +27,10 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CommandDialog::CommandDialog(OSystem& osystem, DialogContainer& parent)
|
||||
: Dialog(osystem, parent)
|
||||
: Dialog(osystem, parent, osystem.frameBuffer().font(), "Commands")
|
||||
{
|
||||
const GUI::Font& font = instance().frameBuffer().font();
|
||||
initTitle(font, "Commands");
|
||||
|
||||
const int buttonWidth = font.getStringWidth("Right Diff B") + 20,
|
||||
buttonHeight = font.getLineHeight() + 6,
|
||||
const int buttonWidth = _font.getStringWidth("Right Diff B") + 20,
|
||||
buttonHeight = _font.getLineHeight() + 6,
|
||||
rowHeight = buttonHeight + 8;
|
||||
|
||||
// Set real dimensions
|
||||
|
@ -46,7 +43,7 @@ CommandDialog::CommandDialog(OSystem& osystem, DialogContainer& parent)
|
|||
|
||||
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);
|
||||
xoffset += buttonWidth + 8;
|
||||
return bw;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
ContextMenu::ContextMenu(GuiObject* boss, const GUI::Font& font,
|
||||
const VariantList& items, int cmd, int width)
|
||||
: Dialog(boss->instance(), boss->parent()),
|
||||
: Dialog(boss->instance(), boss->parent(), font),
|
||||
CommandSender(boss),
|
||||
_rowHeight(font.getLineHeight()),
|
||||
_firstEntry(0),
|
||||
|
@ -39,7 +39,6 @@ ContextMenu::ContextMenu(GuiObject* boss, const GUI::Font& font,
|
|||
_isScrolling(false),
|
||||
_scrollUpColor(kColor),
|
||||
_scrollDnColor(kColor),
|
||||
_font(font),
|
||||
_cmd(cmd),
|
||||
_xorig(0),
|
||||
_yorig(0),
|
||||
|
|
|
@ -120,7 +120,6 @@ class ContextMenu : public Dialog, public CommandSender
|
|||
bool _isScrolling;
|
||||
uInt32 _scrollUpColor, _scrollDnColor;
|
||||
|
||||
const GUI::Font& _font;
|
||||
int _cmd;
|
||||
|
||||
uInt32 _xorig, _yorig;
|
||||
|
|
|
@ -44,13 +44,10 @@
|
|||
* ...
|
||||
*/
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font, const string& title,
|
||||
int x, int y, int w, int h)
|
||||
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),
|
||||
_font(font),
|
||||
_mouseWidget(nullptr),
|
||||
_focusedWidget(nullptr),
|
||||
_dragWidget(nullptr),
|
||||
|
@ -58,30 +55,19 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font
|
|||
_cancelWidget(nullptr),
|
||||
_visible(false),
|
||||
_processCancel(false),
|
||||
_title(title),
|
||||
_th(0),
|
||||
_surface(nullptr),
|
||||
_tabID(0),
|
||||
_flags(WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG)
|
||||
{
|
||||
initTitle(font, title);
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Dialog::Dialog(OSystem& instance, DialogContainer& parent,
|
||||
int x, int y, int w, int h)
|
||||
: GuiObject(instance, parent, *this, x, y, w, h),
|
||||
_font(nullptr),
|
||||
_title(""),
|
||||
_th(0),
|
||||
_fh(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)
|
||||
: Dialog(instance, parent, instance.frameBuffer().font(), "", x, y, w, h)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -133,27 +119,16 @@ void Dialog::close(bool refresh)
|
|||
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;
|
||||
}
|
||||
_title = title;
|
||||
_h -= _th;
|
||||
if(title.empty())
|
||||
_th = 0;
|
||||
else
|
||||
_th = _font.getLineHeight() + 4;
|
||||
_h += _th;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -326,8 +301,8 @@ void Dialog::drawDialog()
|
|||
{
|
||||
// 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();
|
||||
|| (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
|
||||
&& !parent().myDialogStack.top()->hasTitle());
|
||||
|
||||
if(_flags & WIDGET_CLEARBG)
|
||||
{
|
||||
|
@ -336,7 +311,7 @@ void Dialog::drawDialog()
|
|||
if(_th)
|
||||
{
|
||||
s.fillRect(_x, _y, _w, _th, onTop ? kColorTitleBar : kColorTitleBarLo);
|
||||
s.drawString(*_font, _title, _x + 10, _y + 2 + 1, _font->getStringWidth(_title),
|
||||
s.drawString(_font, _title, _x + 10, _y + 2 + 1, _font.getStringWidth(_title),
|
||||
onTop ? kColorTitleText : kColorTitleTextLo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ class Dialog : public GuiObject
|
|||
public:
|
||||
Dialog(OSystem& instance, DialogContainer& parent,
|
||||
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);
|
||||
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();
|
||||
|
||||
|
@ -129,8 +129,6 @@ class Dialog : public GuiObject
|
|||
|
||||
void processCancelWithoutWidget(bool state) { _processCancel = state; }
|
||||
|
||||
void initTitle(const GUI::Font& font, const string& title);
|
||||
|
||||
private:
|
||||
void buildCurrentFocusList(int tabID = -1);
|
||||
bool handleNavEvent(Event::Type e);
|
||||
|
@ -138,18 +136,19 @@ class Dialog : public GuiObject
|
|||
bool cycleTab(int direction);
|
||||
|
||||
protected:
|
||||
const GUI::Font& _font;
|
||||
|
||||
Widget* _mouseWidget;
|
||||
Widget* _focusedWidget;
|
||||
Widget* _dragWidget;
|
||||
Widget* _defaultWidget;
|
||||
Widget* _okWidget;
|
||||
Widget* _cancelWidget;
|
||||
|
||||
bool _visible;
|
||||
bool _processCancel;
|
||||
string _title;
|
||||
int _th;
|
||||
const GUI::Font* _font;
|
||||
int _fh;
|
||||
|
||||
Common::FixedStack<shared_ptr<FBSurface>> mySurfaceStack;
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ GameInfoDialog::GameInfoDialog(
|
|||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight(),
|
||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
const int vBorder = 8;
|
||||
const int hBorder = 8;
|
||||
|
@ -349,7 +348,7 @@ void GameInfoDialog::loadConfig()
|
|||
const string& md5 = instance().launcher().selectedRomMD5();
|
||||
if(md5 != "")
|
||||
{
|
||||
instance().propSet().getMD5(md5, myGameProperties);
|
||||
instance().propSet(md5).getMD5(md5, myGameProperties);
|
||||
myPropertiesLoaded = true;
|
||||
loadView();
|
||||
}
|
||||
|
@ -487,10 +486,13 @@ void GameInfoDialog::saveConfig()
|
|||
myPPBlend->getValueLabel());
|
||||
|
||||
// Determine whether to add or remove an entry from the properties set
|
||||
const string& md5 = myGameProperties.get(Cartridge_MD5);
|
||||
if(myDefaultsSelected)
|
||||
instance().propSet().removeMD5(myGameProperties.get(Cartridge_MD5));
|
||||
instance().propSet(md5).removeMD5(myGameProperties.get(Cartridge_MD5));
|
||||
else
|
||||
instance().propSet().insert(myGameProperties);
|
||||
instance().propSet(md5).insert(myGameProperties);
|
||||
|
||||
instance().saveGamePropSet(myGameProperties.get(Cartridge_MD5));
|
||||
|
||||
// In any event, inform the Console
|
||||
if(instance().hasConsole())
|
||||
|
@ -502,7 +504,7 @@ void GameInfoDialog::setDefaults()
|
|||
{
|
||||
// Load the default properties
|
||||
string md5 = myGameProperties.get(Cartridge_MD5);
|
||||
instance().propSet().getMD5(md5, myGameProperties, true);
|
||||
instance().propSet(md5).getMD5(md5, myGameProperties, true);
|
||||
|
||||
// Reload the current dialog
|
||||
loadView();
|
||||
|
|
|
@ -36,7 +36,6 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font)
|
|||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight(),
|
||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
int xpos, ypos;
|
||||
int lwidth = font.getStringWidth("Right Difficulty "),
|
||||
|
|
|
@ -45,7 +45,6 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
|
|||
{
|
||||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
const int vBorder = 4;
|
||||
int xpos, ypos, tabID;
|
||||
|
|
|
@ -349,7 +349,7 @@ void LauncherDialog::loadRomInfo()
|
|||
|
||||
// Get the properties for this entry
|
||||
Properties props;
|
||||
instance().propSet().getMD5WithInsert(node, myGameList->md5(item), props);
|
||||
instance().propSet(myGameList->md5(item), node).getMD5WithInsert(node, myGameList->md5(item), props);
|
||||
|
||||
myRomInfoWidget->setProperties(props);
|
||||
}
|
||||
|
|
|
@ -48,16 +48,13 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
|
||||
GuiObject* boss, int max_w, int max_h, stellaMode mode)
|
||||
: Dialog(osystem, parent),
|
||||
: Dialog(osystem, parent, osystem.frameBuffer().font(), "Options"),
|
||||
myMode(mode),
|
||||
_boss(boss)
|
||||
{
|
||||
const GUI::Font& font = instance().frameBuffer().font();
|
||||
initTitle(font, "Options");
|
||||
|
||||
const int buttonWidth = font.getStringWidth("Game Properties" + ELLIPSIS) + 20,
|
||||
buttonHeight = font.getLineHeight() + 6,
|
||||
rowHeight = font.getLineHeight() + 10;
|
||||
const int buttonWidth = _font.getStringWidth("Game Properties" + ELLIPSIS) + 20,
|
||||
buttonHeight = _font.getLineHeight() + 6,
|
||||
rowHeight = _font.getLineHeight() + 10;
|
||||
const int VBORDER = 10 + _th;
|
||||
|
||||
_w = 2 * buttonWidth + 30;
|
||||
|
@ -69,7 +66,7 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
|
|||
|
||||
auto ADD_OD_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);
|
||||
yoffset += rowHeight;
|
||||
return bw;
|
||||
|
@ -128,21 +125,21 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
|
|||
addCancelWidget(b);
|
||||
|
||||
// Now create all the dialogs attached to each menu button
|
||||
myVideoDialog = make_unique<VideoDialog>(osystem, parent, font, max_w, max_h);
|
||||
myAudioDialog = make_unique<AudioDialog>(osystem, parent, font);
|
||||
myInputDialog = make_unique<InputDialog>(osystem, parent, font, max_w, max_h);
|
||||
myUIDialog = make_unique<UIDialog>(osystem, parent, font);
|
||||
mySnapshotDialog = make_unique<SnapshotDialog>(osystem, parent, font, max_w, max_h);
|
||||
myConfigPathDialog = make_unique<ConfigPathDialog>(osystem, parent, font, boss, max_w, max_h);
|
||||
myRomAuditDialog = make_unique<RomAuditDialog>(osystem, parent, font, max_w, max_h);
|
||||
myGameInfoDialog = make_unique<GameInfoDialog>(osystem, parent, font, this);
|
||||
myVideoDialog = make_unique<VideoDialog>(osystem, parent, _font, max_w, max_h);
|
||||
myAudioDialog = make_unique<AudioDialog>(osystem, parent, _font);
|
||||
myInputDialog = make_unique<InputDialog>(osystem, parent, _font, max_w, max_h);
|
||||
myUIDialog = make_unique<UIDialog>(osystem, parent, _font);
|
||||
mySnapshotDialog = make_unique<SnapshotDialog>(osystem, parent, _font, max_w, max_h);
|
||||
myConfigPathDialog = make_unique<ConfigPathDialog>(osystem, parent, _font, boss, max_w, max_h);
|
||||
myRomAuditDialog = make_unique<RomAuditDialog>(osystem, parent, _font, max_w, max_h);
|
||||
myGameInfoDialog = make_unique<GameInfoDialog>(osystem, parent, _font, this);
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
myCheatCodeDialog = make_unique<CheatCodeDialog>(osystem, parent, font);
|
||||
myCheatCodeDialog = make_unique<CheatCodeDialog>(osystem, parent, _font);
|
||||
#endif
|
||||
myLoggerDialog = make_unique<LoggerDialog>(osystem, parent, font, max_w, max_h);
|
||||
myDeveloperDialog = make_unique<DeveloperDialog>(osystem, parent, font, max_w, max_h);
|
||||
myHelpDialog = make_unique<HelpDialog>(osystem, parent, font);
|
||||
myAboutDialog = make_unique<AboutDialog>(osystem, parent, font);
|
||||
myLoggerDialog = make_unique<LoggerDialog>(osystem, parent, _font, max_w, max_h);
|
||||
myDeveloperDialog = make_unique<DeveloperDialog>(osystem, parent, _font, max_w, max_h);
|
||||
myHelpDialog = make_unique<HelpDialog>(osystem, parent, _font);
|
||||
myAboutDialog = make_unique<AboutDialog>(osystem, parent, _font);
|
||||
|
||||
addToFocusList(wid);
|
||||
|
||||
|
|
|
@ -263,11 +263,6 @@ void TabWidget::drawWidget(bool hilite)
|
|||
|
||||
FBSurface& s = dialog().surface();
|
||||
|
||||
const int left1 = _x + 1;
|
||||
const int right1 = _x + kTabLeftOffset + _activeTab * (_tabWidth + kTabSpacing);
|
||||
const int left2 = right1 + _tabWidth;
|
||||
const int right2 = _x + _w - 2;
|
||||
|
||||
// Iterate over all tabs and draw them
|
||||
int i, x = _x + kTabLeftOffset;
|
||||
for (i = 0; i < int(_tabs.size()); ++i)
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
#include "TimeLineWidget.hxx"
|
||||
|
||||
const int HANDLE_W = 3;
|
||||
const int HANDLE_H = 3; // size above/below the slider
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int w, int h,
|
||||
|
@ -85,7 +88,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps)
|
|||
if(steps.size() > _stepValue.capacity())
|
||||
_stepValue.reserve(2 * steps.size());
|
||||
|
||||
double scale = (_w - _labelWidth - 2) / double(steps.back());
|
||||
double scale = (_w - _labelWidth - 2 - HANDLE_W*0) / 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)
|
||||
|
@ -93,7 +96,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps)
|
|||
|
||||
// Due to integer <-> double conversion, the last value is sometimes
|
||||
// slightly less than the maximum value; we assign it manually to fix this
|
||||
_stepValue.push_back(_w - _labelWidth - 2);
|
||||
_stepValue.push_back(_w - _labelWidth - 2 - HANDLE_W*0);
|
||||
}
|
||||
else
|
||||
_stepValue.push_back(0);
|
||||
|
@ -142,48 +145,64 @@ 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);
|
||||
isEnabled() ? kTextColor : kColor, TextAlign::Left);
|
||||
|
||||
int p = valueToPos(_value),
|
||||
x = _x + _labelWidth,
|
||||
w = _w - _labelWidth;
|
||||
|
||||
// Frame the handle
|
||||
const int HANDLE_W2 = (HANDLE_W + 1) / 2;
|
||||
s.hLine(x + p - HANDLE_W2, _y + 0, x + p - HANDLE_W2 + HANDLE_W, kColorInfo);
|
||||
s.vLine(x + p - HANDLE_W2, _y + 1, _y + _h - 2, kColorInfo);
|
||||
s.hLine(x + p - HANDLE_W2 + 1, _y + _h - 1, x + p - HANDLE_W2 + 1 + HANDLE_W, kBGColor);
|
||||
s.vLine(x + p - HANDLE_W2 + 1 + HANDLE_W, _y + 1, _y + _h - 2, kBGColor);
|
||||
// Frame the box
|
||||
s.hLine(x, _y + HANDLE_H, x + w - 2, kColorInfo);
|
||||
s.vLine(x, _y + HANDLE_H, _y + _h - 2 - HANDLE_H, kColorInfo);
|
||||
s.hLine(x + 1, _y + _h - 1 - HANDLE_H, x + w - 1, kBGColor);
|
||||
s.vLine(x + w - 1, _y + 1 + HANDLE_H, _y + _h - 2 - HANDLE_H, kBGColor);
|
||||
|
||||
// Draw the box
|
||||
s.frameRect(_x + _labelWidth, _y, _w - _labelWidth, _h, kColor);
|
||||
// Fill the box
|
||||
s.fillRect(_x + _labelWidth + 1, _y + 1, _w - _labelWidth - 2, _h - 2,
|
||||
!isEnabled() ? kBGColorHi : kWidColor);
|
||||
s.fillRect(x + 1, _y + 1 + HANDLE_H, w - 2, _h - 2 - HANDLE_H * 2,
|
||||
!isEnabled() ? kSliderBGColorLo : hilite ? kSliderBGColorHi : kSliderBGColor);
|
||||
// Draw the 'bar'
|
||||
int vp = valueToPos(_value);
|
||||
s.fillRect(_x + _labelWidth + 1, _y + 1, vp, _h - 2,
|
||||
s.fillRect(x + 1, _y + 1 + HANDLE_H, p, _h - 2 - HANDLE_H * 2,
|
||||
!isEnabled() ? kColor : hilite ? kSliderColorHi : kSliderColor);
|
||||
|
||||
// add 4 tickmarks for 5 intervals
|
||||
// Add 4 tickmarks for 5 intervals
|
||||
int numTicks = std::min(5, int(_stepValue.size()));
|
||||
for(int i = 1; i < numTicks; ++i)
|
||||
{
|
||||
int idx = int((_stepValue.size() * i + numTicks / 2) / numTicks);
|
||||
if(idx > 1)
|
||||
{
|
||||
int tp = valueToPos(idx - 1);
|
||||
s.vLine(_x + _labelWidth + tp, _y + _h / 2, _y + _h - 2, tp > vp ? kSliderColor : kWidColor);
|
||||
int xt = x + valueToPos(idx - 1);
|
||||
uInt32 color;
|
||||
|
||||
if(isEnabled())
|
||||
{
|
||||
if(xt > x + p)
|
||||
color = hilite ? kSliderColorHi : kSliderColor;
|
||||
else
|
||||
color = hilite ? kSliderBGColorHi : kSliderBGColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(xt > x + p)
|
||||
color = kColor;
|
||||
else
|
||||
color = kSliderBGColorLo;
|
||||
}
|
||||
s.vLine(xt, _y + _h / 2, _y + _h - 2 - HANDLE_H, color);
|
||||
}
|
||||
}
|
||||
#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,
|
||||
// Draw the handle
|
||||
s.fillRect(x + p + 1 - HANDLE_W2, _y + 1, HANDLE_W, _h - 2,
|
||||
!isEnabled() ? kColor : hilite ? kSliderColorHi : kSliderColor);
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -47,12 +47,25 @@ void TimeMachine::requestResize()
|
|||
{
|
||||
myWidth = newWidth;
|
||||
Dialog* oldPtr = myBaseDialog;
|
||||
Int32 enterWinds = static_cast<TimeMachineDialog*>(myBaseDialog)->getEnterWinds();
|
||||
delete myBaseDialog;
|
||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this, myWidth);
|
||||
setEnterWinds(enterWinds);
|
||||
Dialog* newPtr = myBaseDialog;
|
||||
|
||||
// Update the container stack; it may contain a reference to the old pointer
|
||||
if(oldPtr != newPtr)
|
||||
myDialogStack.replace(oldPtr, newPtr);
|
||||
{
|
||||
myDialogStack.applyAll([&oldPtr,&newPtr](Dialog*& d){
|
||||
if(d == oldPtr)
|
||||
d = newPtr;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeMachine::setEnterWinds(Int32 numWinds)
|
||||
{
|
||||
static_cast<TimeMachineDialog*>(myBaseDialog)->setEnterWinds(numWinds);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,11 @@ class TimeMachine : public DialogContainer
|
|||
*/
|
||||
void requestResize() override;
|
||||
|
||||
/**
|
||||
Set number of winds when entering the dialog.
|
||||
*/
|
||||
void setEnterWinds(Int32 numWinds);
|
||||
|
||||
private:
|
||||
int myWidth;
|
||||
|
||||
|
|
|
@ -34,102 +34,140 @@
|
|||
#include "Base.hxx"
|
||||
using Common::Base;
|
||||
|
||||
|
||||
const int BUTTON_W = 14, BUTTON_H = 14;
|
||||
|
||||
static uInt32 RECORD[BUTTON_H] =
|
||||
{
|
||||
0b00000111100000,
|
||||
0b00011111111000,
|
||||
0b00111111111100,
|
||||
0b01111111111110,
|
||||
0b01111111111110,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b01111111111110,
|
||||
0b01111111111110,
|
||||
0b00111111111100,
|
||||
0b00011111111000,
|
||||
0b00000111100000
|
||||
};
|
||||
|
||||
static uInt32 STOP[BUTTON_H] =
|
||||
{
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111
|
||||
};
|
||||
|
||||
static uInt32 PLAY[BUTTON_H] =
|
||||
{
|
||||
0b11000000000000,
|
||||
0b11110000000000,
|
||||
0b11111100000000,
|
||||
0b11111111000000,
|
||||
0b11111111110000,
|
||||
0b11111111111100,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111100,
|
||||
0b11111111110000,
|
||||
0b11111111000000,
|
||||
0b11111100000000,
|
||||
0b11110000000000,
|
||||
0b11000000000000
|
||||
};
|
||||
static uInt32 REWIND_ALL[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b11000011000011,
|
||||
0b11000111000111,
|
||||
0b11001111001111,
|
||||
0b11011111011111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11011111011111,
|
||||
0b11001111001111,
|
||||
0b11000111000111,
|
||||
0b11000011000011,
|
||||
0
|
||||
};
|
||||
static uInt32 REWIND_1[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b00000110001110,
|
||||
0b00001110001110,
|
||||
0b00011110001110,
|
||||
0b00111110001110,
|
||||
0b01111110001110,
|
||||
0b11111110001110,
|
||||
0b11111110001110,
|
||||
0b01111110001110,
|
||||
0b00111110001110,
|
||||
0b00011110001110,
|
||||
0b00001110001110,
|
||||
0b00000110001110,
|
||||
0
|
||||
};
|
||||
static uInt32 UNWIND_1[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b01110001100000,
|
||||
0b01110001110000,
|
||||
0b01110001111000,
|
||||
0b01110001111100,
|
||||
0b01110001111110,
|
||||
0b01110001111111,
|
||||
0b01110001111111,
|
||||
0b01110001111110,
|
||||
0b01110001111100,
|
||||
0b01110001111000,
|
||||
0b01110001110000,
|
||||
0b01110001100000,
|
||||
0
|
||||
};
|
||||
static uInt32 UNWIND_ALL[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b11000011000011,
|
||||
0b11100011100011,
|
||||
0b11110011110011,
|
||||
0b11111011111011,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111111111111,
|
||||
0b11111011111011,
|
||||
0b11110011110011,
|
||||
0b11100011100011,
|
||||
0b11000011000011,
|
||||
0
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||
int width)
|
||||
: Dialog(osystem, parent)
|
||||
: Dialog(osystem, parent),
|
||||
_enterWinds(0)
|
||||
{
|
||||
const int BUTTON_W = 16, BUTTON_H = 14;
|
||||
|
||||
static uInt32 PLAY[BUTTON_H] =
|
||||
{
|
||||
0b0110000000000000,
|
||||
0b0111100000000000,
|
||||
0b0111111000000000,
|
||||
0b0111111110000000,
|
||||
0b0111111111100000,
|
||||
0b0111111111111000,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0111111111111000,
|
||||
0b0111111111100000,
|
||||
0b0111111110000000,
|
||||
0b0111111000000000,
|
||||
0b0111100000000000,
|
||||
0b0110000000000000
|
||||
};
|
||||
static uInt32 REWIND_ALL[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b0110000110000110,
|
||||
0b0110001110001110,
|
||||
0b0110011110011110,
|
||||
0b0110111110111110,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0110111110111110,
|
||||
0b0110011110011110,
|
||||
0b0110001110001110,
|
||||
0b0110000110000110,
|
||||
0
|
||||
};
|
||||
static uInt32 REWIND_1[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b0000001100011100,
|
||||
0b0000011100011100,
|
||||
0b0000111100011100,
|
||||
0b0001111100011100,
|
||||
0b0011111100011100,
|
||||
0b0111111100011100,
|
||||
0b0111111100011100,
|
||||
0b0011111100011100,
|
||||
0b0001111100011100,
|
||||
0b0000111100011100,
|
||||
0b0000011100011100,
|
||||
0b0000001100011100,
|
||||
0
|
||||
};
|
||||
static uInt32 UNWIND_1[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b0011100011000000,
|
||||
0b0011100011100000,
|
||||
0b0011100011110000,
|
||||
0b0011100011111000,
|
||||
0b0011100011111100,
|
||||
0b0011100011111110,
|
||||
0b0011100011111110,
|
||||
0b0011100011111100,
|
||||
0b0011100011111000,
|
||||
0b0011100011110000,
|
||||
0b0011100011100000,
|
||||
0b0011100011000000,
|
||||
0
|
||||
};
|
||||
static uInt32 UNWIND_ALL[BUTTON_H] =
|
||||
{
|
||||
0,
|
||||
0b0110000110000110,
|
||||
0b0111000111000110,
|
||||
0b0111100111100110,
|
||||
0b0111110111110110,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0111110111110110,
|
||||
0b0111100111100110,
|
||||
0b0111000111000110,
|
||||
0b0110000110000110,
|
||||
0
|
||||
};
|
||||
|
||||
const GUI::Font& font = instance().frameBuffer().font();
|
||||
const int H_BORDER = 6, BUTTON_GAP = 4, V_BORDER = 4;
|
||||
const int buttonWidth = BUTTON_W + 8,
|
||||
const int buttonWidth = BUTTON_W + 10,
|
||||
buttonHeight = BUTTON_H + 10,
|
||||
rowHeight = font.getLineHeight();
|
||||
|
||||
|
@ -146,41 +184,45 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
ypos = V_BORDER;
|
||||
|
||||
// Add index info
|
||||
myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, " ", TextAlign::Left, kBGColor);
|
||||
myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, "1000", TextAlign::Left, kBGColor);
|
||||
myCurrentIdxWidget->setTextColor(kColorInfo);
|
||||
myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("8888"), ypos,
|
||||
" ", TextAlign::Right, kBGColor);
|
||||
myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("1000"), ypos,
|
||||
"1000", TextAlign::Right, kBGColor);
|
||||
myLastIdxWidget->setTextColor(kColorInfo);
|
||||
|
||||
// Add timeline
|
||||
const uInt32 tl_h = myCurrentIdxWidget->getHeight() / 2,
|
||||
tl_x = xpos + myCurrentIdxWidget->getWidth() + 8,
|
||||
tl_y = ypos + (myCurrentIdxWidget->getHeight() - tl_h) / 2 - 1,
|
||||
tl_w = myLastIdxWidget->getAbsX() - tl_x - 8;
|
||||
const uInt32 tl_h = myCurrentIdxWidget->getHeight() / 2 + 6,
|
||||
tl_x = xpos + myCurrentIdxWidget->getWidth() + 8,
|
||||
tl_y = ypos + (myCurrentIdxWidget->getHeight() - tl_h) / 2 - 1,
|
||||
tl_w = myLastIdxWidget->getAbsX() - tl_x - 8;
|
||||
myTimeline = new TimeLineWidget(this, font, tl_x, tl_y, tl_w, tl_h, "", 0, kTimeline);
|
||||
myTimeline->setMinValue(0);
|
||||
ypos += rowHeight;
|
||||
|
||||
// Add time info
|
||||
myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos + 3, "04:32 59", TextAlign::Left, kBGColor);
|
||||
myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos + 3, "00:00.00", TextAlign::Left, kBGColor);
|
||||
myCurrentTimeWidget->setTextColor(kColorInfo);
|
||||
myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("XX:XX XX"), ypos + 3,
|
||||
"12:25 59", TextAlign::Right, kBGColor);
|
||||
myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("00:00.00"), ypos + 3,
|
||||
"00:00.00", TextAlign::Right, kBGColor);
|
||||
myLastTimeWidget->setTextColor(kColorInfo);
|
||||
xpos = myCurrentTimeWidget->getRight() + BUTTON_GAP * 4;
|
||||
|
||||
// Add buttons
|
||||
myToggleWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, STOP,
|
||||
BUTTON_W, BUTTON_H, kToggle);
|
||||
xpos += buttonWidth + BUTTON_GAP;
|
||||
|
||||
myPlayWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, PLAY,
|
||||
BUTTON_W, BUTTON_H, kPlay);
|
||||
xpos += buttonWidth + BUTTON_GAP * 4;
|
||||
|
||||
myRewindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_ALL,
|
||||
BUTTON_W, BUTTON_H, kRewindAll);
|
||||
xpos += buttonWidth + BUTTON_GAP;
|
||||
|
||||
myRewind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_1,
|
||||
BUTTON_W, BUTTON_H, kRewind1);
|
||||
xpos += buttonWidth + BUTTON_GAP*2;
|
||||
|
||||
myPlayWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, PLAY,
|
||||
BUTTON_W, BUTTON_H, kPlay);
|
||||
xpos += buttonWidth + BUTTON_GAP*2;
|
||||
xpos += buttonWidth + BUTTON_GAP;
|
||||
|
||||
myUnwind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_1,
|
||||
BUTTON_W, BUTTON_H, kUnwind1);
|
||||
|
@ -188,7 +230,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
|
||||
myUnwindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_ALL,
|
||||
BUTTON_W, BUTTON_H, kUnwindAll);
|
||||
xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3;
|
||||
xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 4;
|
||||
|
||||
// Add message
|
||||
myMessageWidget = new StaticTextWidget(this, font, xpos, ypos + 3, " ",
|
||||
|
@ -224,8 +266,10 @@ void TimeMachineDialog::loadConfig()
|
|||
surface().applyAttributes();
|
||||
}
|
||||
|
||||
handleWinds();
|
||||
myMessageWidget->setLabel("");
|
||||
handleWinds(_enterWinds);
|
||||
_enterWinds = 0;
|
||||
handleToggle();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -278,6 +322,11 @@ void TimeMachineDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
break;
|
||||
}
|
||||
|
||||
case kToggle:
|
||||
instance().state().toggleTimeMachine();
|
||||
handleToggle();
|
||||
break;
|
||||
|
||||
case kPlay:
|
||||
instance().eventHandler().leaveMenuMode();
|
||||
break;
|
||||
|
@ -368,3 +417,11 @@ void TimeMachineDialog::handleWinds(Int32 numWinds)
|
|||
myUnwindAllWidget->setEnabled(!r.atLast());
|
||||
myUnwind1Widget->setEnabled(!r.atLast());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeMachineDialog::handleToggle()
|
||||
{
|
||||
myToggleWidget->setBitmap(instance().state().mode() == StateManager::Mode::Off ? RECORD : STOP,
|
||||
BUTTON_W, BUTTON_H);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ class TimeMachineDialog : public Dialog
|
|||
TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int width);
|
||||
virtual ~TimeMachineDialog() = default;
|
||||
|
||||
/** set/get number of winds when entering the dialog */
|
||||
void setEnterWinds(Int32 numWinds) { _enterWinds = numWinds; }
|
||||
Int32 getEnterWinds() { return _enterWinds; }
|
||||
|
||||
private:
|
||||
void loadConfig() override;
|
||||
void handleKeyDown(StellaKey key, StellaMod mod) override;
|
||||
|
@ -43,11 +47,14 @@ class TimeMachineDialog : public Dialog
|
|||
string getTimeString(uInt64 cycles);
|
||||
/** re/unwind and update display */
|
||||
void handleWinds(Int32 numWinds = 0);
|
||||
/** toggle Time Machine mode */
|
||||
void handleToggle();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kTimeline = 'TMtl',
|
||||
kToggle = 'TMtg',
|
||||
kPlay = 'TMpl',
|
||||
kRewindAll = 'TMra',
|
||||
kRewind10 = 'TMr1',
|
||||
|
@ -59,6 +66,7 @@ class TimeMachineDialog : public Dialog
|
|||
|
||||
TimeLineWidget* myTimeline;
|
||||
|
||||
ButtonWidget* myToggleWidget;
|
||||
ButtonWidget* myPlayWidget;
|
||||
ButtonWidget* myRewindAllWidget;
|
||||
ButtonWidget* myRewind1Widget;
|
||||
|
@ -72,6 +80,8 @@ class TimeMachineDialog : public Dialog
|
|||
StaticTextWidget* myLastIdxWidget;
|
||||
StaticTextWidget* myMessageWidget;
|
||||
|
||||
Int32 _enterWinds;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
TimeMachineDialog() = delete;
|
||||
|
|
|
@ -41,7 +41,6 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
|
|||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight(),
|
||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
const int VBORDER = 8;
|
||||
const int HBORDER = 10;
|
||||
|
@ -49,7 +48,6 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
|
|||
int lwidth, pwidth = font.getStringWidth("Standard");
|
||||
WidgetArray wid;
|
||||
VariantList items;
|
||||
ButtonWidget* b;
|
||||
const GUI::Size& ds = instance().frameBuffer().desktopSize();
|
||||
|
||||
// Set real dimensions
|
||||
|
|
|
@ -44,7 +44,6 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
|
|||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight(),
|
||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
int xpos, ypos, tabID;
|
||||
int lwidth = font.getStringWidth("TIA Palette "),
|
||||
|
|
|
@ -435,6 +435,15 @@ void ButtonWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ButtonWidget::setBitmap(uInt32* bitmap, int bmw, int bmh)
|
||||
{
|
||||
_bitmap = bitmap;
|
||||
_bmh = bmh;
|
||||
_bmw = bmw;
|
||||
_useBitmap = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ButtonWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
@ -635,10 +644,10 @@ SliderWidget::SliderWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_valueMax(100),
|
||||
_isDragging(false),
|
||||
_labelWidth(labelWidth),
|
||||
_valueLabelGap(valueLabelGap),
|
||||
_valueLabelWidth(valueLabelWidth),
|
||||
_valueLabel(""),
|
||||
_valueUnit(valueUnit),
|
||||
_valueLabelGap(valueLabelGap),
|
||||
_valueLabelWidth(valueLabelWidth),
|
||||
_numIntervals(0)
|
||||
{
|
||||
_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE;
|
||||
|
|
|
@ -229,6 +229,8 @@ class ButtonWidget : public StaticTextWidget, public CommandSender
|
|||
|
||||
void setCmd(int cmd) { _cmd = cmd; }
|
||||
int getCmd() const { return _cmd; }
|
||||
/* Sets/changes the button's bitmap **/
|
||||
void setBitmap(uInt32* bitmap, int bmw, int bmh);
|
||||
|
||||
protected:
|
||||
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
|
||||
|
@ -349,8 +351,8 @@ class SliderWidget : public ButtonWidget
|
|||
int _labelWidth;
|
||||
string _valueLabel;
|
||||
string _valueUnit;
|
||||
int _valueLabelWidth;
|
||||
int _valueLabelGap;
|
||||
int _valueLabelWidth;
|
||||
int _numIntervals;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue