mirror of https://github.com/stella-emu/stella.git
UI partially working now (TODO: timebar)
This commit is contained in:
parent
96fceed896
commit
cf926fdf07
|
@ -68,6 +68,10 @@ 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
|
||||||
|
std::snprintf(vToS_buf, 3, "%02d", 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;
|
||||||
|
|
|
@ -47,6 +47,7 @@ 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_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
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "Serializer.hxx"
|
#include "Serializer.hxx"
|
||||||
#include "StateManager.hxx"
|
#include "StateManager.hxx"
|
||||||
#include "TIA.hxx"
|
#include "TIA.hxx"
|
||||||
|
#include "EventHandler.hxx"
|
||||||
|
|
||||||
#include "RewindManager.hxx"
|
#include "RewindManager.hxx"
|
||||||
|
|
||||||
|
@ -170,7 +171,8 @@ uInt32 RewindManager::rewindState(uInt32 numStates)
|
||||||
else
|
else
|
||||||
message = "Rewind not possible";
|
message = "Rewind not possible";
|
||||||
|
|
||||||
myOSystem.frameBuffer().showMessage(message);
|
if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE)
|
||||||
|
myOSystem.frameBuffer().showMessage(message);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +205,8 @@ uInt32 RewindManager::unwindState(uInt32 numStates)
|
||||||
else
|
else
|
||||||
message = "Unwind not possible";
|
message = "Unwind not possible";
|
||||||
|
|
||||||
myOSystem.frameBuffer().showMessage(message);
|
if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE)
|
||||||
|
myOSystem.frameBuffer().showMessage(message);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +279,7 @@ string RewindManager::loadState(Int64 startCycles, uInt32 numStates)
|
||||||
string RewindManager::getUnitString(Int64 cycles)
|
string RewindManager::getUnitString(Int64 cycles)
|
||||||
{
|
{
|
||||||
const Int32 scanlines = std::max(myOSystem.console().tia().scanlinesLastFrame(), 240u);
|
const Int32 scanlines = std::max(myOSystem.console().tia().scanlinesLastFrame(), 240u);
|
||||||
const bool isNTSC = scanlines <= 285; // TODO: replace magic number
|
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
|
||||||
|
@ -304,3 +307,27 @@ string RewindManager::getUnitString(Int64 cycles)
|
||||||
|
|
||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 RewindManager::getFirstCycles()
|
||||||
|
{
|
||||||
|
// TODO: check if valid
|
||||||
|
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.first())->cycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 RewindManager::getCurrentCycles()
|
||||||
|
{
|
||||||
|
if(myStateList.currentIsValid())
|
||||||
|
return myStateList.current().cycles;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 RewindManager::getLastCycles()
|
||||||
|
{
|
||||||
|
// TODO: check if valid
|
||||||
|
return Common::LinkedObjectPool<RewindState>::const_iter(myStateList.last())->cycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,13 @@ class RewindManager
|
||||||
*/
|
*/
|
||||||
string getUnitString(Int64 cycles);
|
string getUnitString(Int64 cycles);
|
||||||
|
|
||||||
|
uInt32 getCurrentIdx() { return myStateList.currentIdx(); }
|
||||||
|
uInt32 getLastIdx() { return myStateList.size(); }
|
||||||
|
|
||||||
|
uInt32 getFirstCycles();
|
||||||
|
uInt32 getCurrentCycles();
|
||||||
|
uInt32 getLastCycles();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OSystem& myOSystem;
|
OSystem& myOSystem;
|
||||||
StateManager& myStateManager;
|
StateManager& myStateManager;
|
||||||
|
|
|
@ -24,7 +24,17 @@
|
||||||
#include "Widget.hxx"
|
#include "Widget.hxx"
|
||||||
#include "StateManager.hxx"
|
#include "StateManager.hxx"
|
||||||
#include "RewindManager.hxx"
|
#include "RewindManager.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
#include "Console.hxx"
|
||||||
|
#include "TIA.hxx"
|
||||||
|
#include "System.hxx"
|
||||||
|
|
||||||
|
|
||||||
#include "TimeMachineDialog.hxx"
|
#include "TimeMachineDialog.hxx"
|
||||||
|
#include "Base.hxx"
|
||||||
|
using Common::Base;
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
|
@ -188,17 +198,19 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
xpos = H_BORDER;
|
xpos = H_BORDER;
|
||||||
ypos = V_BORDER;
|
ypos = V_BORDER;
|
||||||
|
|
||||||
// Add frame info
|
// Add index info
|
||||||
new StaticTextWidget(this, font, xpos, ypos, "04:32 190");
|
myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, " ");
|
||||||
|
myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("8888"), ypos,
|
||||||
new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("XX:XX XXX"), ypos, "12:25 144");
|
" ", TextAlign::Right);
|
||||||
|
|
||||||
ypos += rowHeight;
|
ypos += rowHeight;
|
||||||
|
|
||||||
StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos + 3, "999");
|
// Add time info
|
||||||
new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("8888"), ypos + 3, "1000");
|
myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos + 3, "04:32 59");
|
||||||
xpos = t->getRight() + 16;
|
myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("XX:XX XX"), ypos + 3,
|
||||||
|
"12:25 59");
|
||||||
|
xpos = myCurrentTimeWidget->getRight() + BUTTON_GAP * 4;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
@ -236,7 +248,10 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
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 += buttonWidth + BUTTON_GAP;
|
xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3;
|
||||||
|
|
||||||
|
// Add message
|
||||||
|
myMessageWidget = new StaticTextWidget(this, font, xpos, ypos + 3, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -252,6 +267,7 @@ void TimeMachineDialog::center()
|
||||||
void TimeMachineDialog::loadConfig()
|
void TimeMachineDialog::loadConfig()
|
||||||
{
|
{
|
||||||
handleWinds();
|
handleWinds();
|
||||||
|
myMessageWidget->setLabel("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -294,20 +310,51 @@ cerr << cmd << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string TimeMachineDialog::getTimeString(uInt64 cycles)
|
||||||
|
{
|
||||||
|
const Int32 scanlines = std::max(instance().console().tia().scanlinesLastFrame(), 240u);
|
||||||
|
const bool isNTSC = scanlines <= 287;
|
||||||
|
const Int32 NTSC_FREQ = 1193182; // ~76*262*60
|
||||||
|
const Int32 PAL_FREQ = 1182298; // ~76*312*50
|
||||||
|
const Int32 freq = isNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second
|
||||||
|
|
||||||
|
uInt32 minutes = cycles / (freq * 60);
|
||||||
|
cycles -= minutes * (freq * 60);
|
||||||
|
uInt32 seconds = cycles / freq;
|
||||||
|
cycles -= seconds * freq;
|
||||||
|
uInt32 frames = cycles / (scanlines * 76);
|
||||||
|
|
||||||
|
stringstream time;
|
||||||
|
time << Common::Base::toString(minutes, 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);
|
||||||
|
|
||||||
|
return time.str();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TimeMachineDialog::handleWinds(Int32 numWinds)
|
void TimeMachineDialog::handleWinds(Int32 numWinds)
|
||||||
{
|
{
|
||||||
RewindManager& r = instance().state().rewindManager();
|
RewindManager& r = instance().state().rewindManager();
|
||||||
|
|
||||||
if(numWinds < 0)
|
if(numWinds)
|
||||||
r.rewindState(-numWinds);
|
{
|
||||||
else if(numWinds > 0)
|
uInt64 startCycles = instance().console().tia().cycles();
|
||||||
r.unwindState(numWinds);
|
uInt32 winds = numWinds < 0 ? r.rewindState(-numWinds) : r.unwindState(numWinds);
|
||||||
|
string message = r.getUnitString(instance().console().tia().cycles() - startCycles);
|
||||||
|
|
||||||
|
myMessageWidget->setLabel((numWinds < 0 ? "(-" : "(+") + message + ")");
|
||||||
|
}
|
||||||
|
// Update time
|
||||||
|
myCurrentTimeWidget->setLabel(getTimeString(r.getCurrentCycles() - r.getFirstCycles()));
|
||||||
|
myLastTimeWidget->setLabel(getTimeString(r.getLastCycles() - r.getFirstCycles()));
|
||||||
|
// Update index
|
||||||
|
myCurrentIdxWidget->setValue(r.getCurrentIdx());
|
||||||
|
myLastIdxWidget->setValue(r.getLastIdx());
|
||||||
|
// enable/disable buttons
|
||||||
myRewindAllWidget->setEnabled(!r.atFirst());
|
myRewindAllWidget->setEnabled(!r.atFirst());
|
||||||
myRewind10Widget->setEnabled(!r.atFirst());
|
myRewind10Widget->setEnabled(!r.atFirst());
|
||||||
myRewind1Widget->setEnabled(!r.atFirst());
|
myRewind1Widget->setEnabled(!r.atFirst());
|
||||||
|
|
||||||
myUnwindAllWidget->setEnabled(!r.atLast());
|
myUnwindAllWidget->setEnabled(!r.atLast());
|
||||||
myUnwind10Widget->setEnabled(!r.atLast());
|
myUnwind10Widget->setEnabled(!r.atLast());
|
||||||
myUnwind1Widget->setEnabled(!r.atLast());
|
myUnwind1Widget->setEnabled(!r.atLast());
|
||||||
|
|
|
@ -37,6 +37,9 @@ class TimeMachineDialog : public Dialog
|
||||||
/** This dialog uses its own positioning, so we override Dialog::center() */
|
/** This dialog uses its own positioning, so we override Dialog::center() */
|
||||||
void center() override;
|
void center() override;
|
||||||
|
|
||||||
|
/** convert cycles into time */
|
||||||
|
string getTimeString(uInt64 cycles);
|
||||||
|
/** re/unwind and update display */
|
||||||
void handleWinds(Int32 numWinds = 0);
|
void handleWinds(Int32 numWinds = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -61,6 +64,13 @@ class TimeMachineDialog : public Dialog
|
||||||
ButtonWidget* myUnwind10Widget;
|
ButtonWidget* myUnwind10Widget;
|
||||||
ButtonWidget* myUnwindAllWidget;
|
ButtonWidget* myUnwindAllWidget;
|
||||||
|
|
||||||
|
StaticTextWidget* myCurrentTimeWidget;
|
||||||
|
StaticTextWidget* myLastTimeWidget;
|
||||||
|
|
||||||
|
StaticTextWidget* myCurrentIdxWidget;
|
||||||
|
StaticTextWidget* myLastIdxWidget;
|
||||||
|
StaticTextWidget* myMessageWidget;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
TimeMachineDialog() = delete;
|
TimeMachineDialog() = delete;
|
||||||
|
|
Loading…
Reference in New Issue