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