Timeline and buttons in TimeMachineDialog are now syncronized.

This commit is contained in:
Stephen Anthony 2018-01-27 19:34:26 -03:30
parent 307e496109
commit 2c90aaa7c7
7 changed files with 74 additions and 34 deletions

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

@ -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");
@ -146,7 +146,7 @@ uInt32 RewindManager::rewindState(uInt32 numStates)
for(i = 0; i < numStates; ++i) for(i = 0; i < numStates; ++i)
{ {
if(!atFirst()) if(!atFirst())
{ {
if(!myLastTimeMachineAdd) if(!myLastTimeMachineAdd)
// Set internal current iterator to previous state (back in time), // Set internal current iterator to previous state (back in time),
@ -306,14 +306,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 +322,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.first(); it != myStateList.last(); ++it)
arr.push_back(uInt32(it->cycles - firstCycle));
return arr;
}

View File

@ -136,9 +136,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

@ -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

@ -73,11 +73,13 @@ void TimeLineWidget::setMaxValue(int value)
_valueMax = value; _valueMax = value;
} }
#if 0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::setStepValue(int value) void TimeLineWidget::setStepValue(int value)
{ {
_stepValue = value; _stepValue = value;
} }
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeLineWidget::handleMouseMoved(int x, int y) void TimeLineWidget::handleMouseMoved(int x, int y)

View File

@ -34,8 +34,10 @@ class TimeLineWidget : public ButtonWidget
int getMinValue() const { return _valueMin; } int getMinValue() const { return _valueMin; }
void setMaxValue(int value); void setMaxValue(int value);
int getMaxValue() const { return _valueMax; } int getMaxValue() const { return _valueMax; }
#if 0
void setStepValue(int value); void setStepValue(int value);
int getStepValue() const { return _stepValue; } int getStepValue() const { return _stepValue; }
#endif
protected: protected:
void handleMouseMoved(int x, int y) override; void handleMouseMoved(int x, int y) override;

View File

@ -179,12 +179,12 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
}; };
const GUI::Font& font = instance().frameBuffer().font(); const GUI::Font& font = instance().frameBuffer().font();
const int H_BORDER = 6, BUTTON_GAP = 4, V_BORDER = 4; // FIXME, V_GAP = 4; const int H_BORDER = 6, BUTTON_GAP = 4, V_BORDER = 4;
const int buttonWidth = BUTTON_W + 8, const int buttonWidth = BUTTON_W + 8,
buttonHeight = BUTTON_H + 10, buttonHeight = BUTTON_H + 10,
rowHeight = font.getLineHeight(); rowHeight = font.getLineHeight();
WidgetArray wid; // WidgetArray wid;
int xpos, ypos; int xpos, ypos;
// Set real dimensions // Set real dimensions
@ -210,7 +210,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
tl_y = ypos + (myCurrentIdxWidget->getHeight() - tl_h) / 2, tl_y = ypos + (myCurrentIdxWidget->getHeight() - tl_h) / 2,
tl_w = myLastIdxWidget->getAbsX() - tl_x - 8; tl_w = myLastIdxWidget->getAbsX() - tl_x - 8;
myTimeline = new TimeLineWidget(this, font, tl_x, tl_y, tl_w, tl_h, "", 0, kTimeline); myTimeline = new TimeLineWidget(this, font, tl_x, tl_y, tl_w, tl_h, "", 0, kTimeline);
wid.push_back(myTimeline); // wid.push_back(myTimeline);
ypos += rowHeight; ypos += rowHeight;
// Add time info // Add time info
@ -224,37 +224,37 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
// Add buttons // Add buttons
myRewindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_ALL, myRewindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_ALL,
BUTTON_W, BUTTON_H, kRewindAll); BUTTON_W, BUTTON_H, kRewindAll);
wid.push_back(myRewindAllWidget); // wid.push_back(myRewindAllWidget);
xpos += buttonWidth + BUTTON_GAP; xpos += buttonWidth + BUTTON_GAP;
myRewind10Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_10, myRewind10Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_10,
BUTTON_W, BUTTON_H, kRewind10); BUTTON_W, BUTTON_H, kRewind10);
wid.push_back(myRewind10Widget); // wid.push_back(myRewind10Widget);
xpos += buttonWidth + BUTTON_GAP; xpos += buttonWidth + BUTTON_GAP;
myRewind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_1, myRewind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, REWIND_1,
BUTTON_W, BUTTON_H, kRewind1); BUTTON_W, BUTTON_H, kRewind1);
wid.push_back(myRewind1Widget); // wid.push_back(myRewind1Widget);
xpos += buttonWidth + BUTTON_GAP*2; xpos += buttonWidth + BUTTON_GAP*2;
myPlayWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, PLAY, myPlayWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, PLAY,
BUTTON_W, BUTTON_H, kPlay); BUTTON_W, BUTTON_H, kPlay);
wid.push_back(myPlayWidget); // wid.push_back(myPlayWidget);
xpos += buttonWidth + BUTTON_GAP*2; xpos += buttonWidth + BUTTON_GAP*2;
myUnwind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_1, myUnwind1Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_1,
BUTTON_W, BUTTON_H, kUnwind1); BUTTON_W, BUTTON_H, kUnwind1);
wid.push_back(myUnwind1Widget); // wid.push_back(myUnwind1Widget);
xpos += buttonWidth + BUTTON_GAP; xpos += buttonWidth + BUTTON_GAP;
myUnwind10Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_10, myUnwind10Widget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_10,
BUTTON_W, BUTTON_H, kUnwind10); BUTTON_W, BUTTON_H, kUnwind10);
wid.push_back(myUnwind10Widget); // wid.push_back(myUnwind10Widget);
xpos += buttonWidth + BUTTON_GAP; xpos += buttonWidth + BUTTON_GAP;
myUnwindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_ALL, myUnwindAllWidget = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, UNWIND_ALL,
BUTTON_W, BUTTON_H, kUnwindAll); BUTTON_W, BUTTON_H, kUnwindAll);
wid.push_back(myUnwindAllWidget); // wid.push_back(myUnwindAllWidget);
xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3; xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3;
// Add message // Add message
@ -262,7 +262,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
TextAlign::Left, kBGColor); TextAlign::Left, kBGColor);
myMessageWidget->setTextColor(kWidColor); myMessageWidget->setTextColor(kWidColor);
// FIXME - add wid list to focus list // addToFocusList(wid);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -277,13 +277,29 @@ void TimeMachineDialog::center()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimeMachineDialog::loadConfig() void TimeMachineDialog::loadConfig()
{ {
cerr << "loadConfig()\n"; RewindManager& r = instance().state().rewindManager();
// FIXME - set range for timeline IntArray cycles = r.cyclesList();
//myTimeline->setMinValue(..); myTimeline->setMaxValue(..);
surface().attributes().blending = true; #if 0 // if we won't be using focused widget, this code can disappear
surface().attributes().blendalpha = 80; // Set default focus
surface().applyAttributes(); bool timelineEnabled = cycles.size() > 0;
myTimeline->setEnabled(timelineEnabled);
if(timelineEnabled)
setFocus(myTimeline);
else
setFocus(myPlayWidget);
#endif
// Set range for timeline
myTimeline->setMaxValue(std::max(Int32(cycles.size()), 1));
// Enable blending (only once is necessary)
if(!surface().attributes().blending)
{
surface().attributes().blending = true;
surface().attributes().blendalpha = 80;
surface().applyAttributes();
}
handleWinds(); handleWinds();
myMessageWidget->setLabel(""); myMessageWidget->setLabel("");
@ -296,8 +312,12 @@ void TimeMachineDialog::handleCommand(CommandSender* sender, int cmd,
switch(cmd) switch(cmd)
{ {
case kTimeline: case kTimeline:
cerr << "timeline: " << myTimeline->getValue() << endl; {
Int32 winds = myTimeline->getValue() -
instance().state().rewindManager().getCurrentIdx() + 1;
handleWinds(winds);
break; break;
}
case kPlay: case kPlay:
instance().eventHandler().leaveMenuMode(); instance().eventHandler().leaveMenuMode();
@ -338,7 +358,7 @@ string TimeMachineDialog::getTimeString(uInt64 cycles)
const Int32 scanlines = std::max(instance().console().tia().scanlinesLastFrame(), 240u); const Int32 scanlines = std::max(instance().console().tia().scanlinesLastFrame(), 240u);
const bool isNTSC = scanlines <= 287; const bool isNTSC = scanlines <= 287;
const Int32 NTSC_FREQ = 1193182; // ~76*262*60 const Int32 NTSC_FREQ = 1193182; // ~76*262*60
const Int32 PAL_FREQ = 1182298; // ~76*312*50 const Int32 PAL_FREQ = 1182298; // ~76*312*50
const Int32 freq = isNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second const Int32 freq = isNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second
uInt32 minutes = cycles / (freq * 60); uInt32 minutes = cycles / (freq * 60);
@ -347,7 +367,7 @@ string TimeMachineDialog::getTimeString(uInt64 cycles)
cycles -= seconds * freq; cycles -= seconds * freq;
uInt32 frames = cycles / (scanlines * 76); uInt32 frames = cycles / (scanlines * 76);
stringstream time; ostringstream time;
time << Common::Base::toString(minutes, Common::Base::F_10_2) << ":"; time << Common::Base::toString(minutes, Common::Base::F_10_2) << ":";
time << Common::Base::toString(seconds, Common::Base::F_10_2) << "."; time << Common::Base::toString(seconds, Common::Base::F_10_2) << ".";
time << Common::Base::toString(frames, Common::Base::F_10_2); time << Common::Base::toString(frames, Common::Base::F_10_2);
@ -363,10 +383,8 @@ void TimeMachineDialog::handleWinds(Int32 numWinds)
if(numWinds) if(numWinds)
{ {
uInt64 startCycles = instance().console().tia().cycles(); uInt64 startCycles = instance().console().tia().cycles();
if(numWinds < 0) if(numWinds < 0) r.rewindState(-numWinds);
r.rewindState(-numWinds); else if(numWinds > 0) r.unwindState(numWinds);
else
r.unwindState(numWinds);
string message = r.getUnitString(instance().console().tia().cycles() - startCycles); string message = r.getUnitString(instance().console().tia().cycles() - startCycles);
myMessageWidget->setLabel((numWinds < 0 ? "(-" : "(+") + message + ")"); myMessageWidget->setLabel((numWinds < 0 ? "(-" : "(+") + message + ")");
@ -374,6 +392,7 @@ void TimeMachineDialog::handleWinds(Int32 numWinds)
// Update time // Update time
myCurrentTimeWidget->setLabel(getTimeString(r.getCurrentCycles() - r.getFirstCycles())); myCurrentTimeWidget->setLabel(getTimeString(r.getCurrentCycles() - r.getFirstCycles()));
myLastTimeWidget->setLabel(getTimeString(r.getLastCycles() - r.getFirstCycles())); myLastTimeWidget->setLabel(getTimeString(r.getLastCycles() - r.getFirstCycles()));
myTimeline->setValue(r.getCurrentIdx()-1);
// Update index // Update index
myCurrentIdxWidget->setValue(r.getCurrentIdx()); myCurrentIdxWidget->setValue(r.getCurrentIdx());
myLastIdxWidget->setValue(r.getLastIdx()); myLastIdxWidget->setValue(r.getLastIdx());