Merge branch 'master' into feature/filesystem

This commit is contained in:
Stephen Anthony 2022-10-08 14:28:30 -02:30
commit d27b8e05dc
7 changed files with 221 additions and 136 deletions

View File

@ -866,10 +866,9 @@ measure the minimum, maximum and average cycles executed between their two
timer points. Start and end points can be set via prompt command or ROM timer points. Start and end points can be set via prompt command or ROM
Disassembly settings dialog.</p> Disassembly settings dialog.</p>
<p>Timer points can be defined with or without a bank. With a bank, they <p>If the timer point is defined without an address or bank, the current PC
are triggered in the given bank only, using all mirror addresses too. Without address or bank are used. If a '+' is added, both timer points use address
a bank, the timer points are triggered in all bank, using the given adress mirrors too, a '*' triggers both timer points in any bank.</p>
only.</p>
<p>All timers can be shown in detail with "listTimers", a single timer <p>All timers can be shown in detail with "listTimers", a single timer
with "printTimer number". "resetTimers" allows resetting all timer statistics, with "printTimer number". "resetTimers" allows resetting all timer statistics,

View File

@ -593,13 +593,16 @@ void DebuggerParser::printTimer(uInt32 idx, bool showHeader)
if(!debugger.cartDebug().getLabel(buf, timer.from.addr, true)) if(!debugger.cartDebug().getLabel(buf, timer.from.addr, true))
buf << " $" << setw(4) << Base::HEX4 << timer.from.addr; buf << " $" << setw(4) << Base::HEX4 << timer.from.addr;
string labelFrom = buf.str(); string labelFrom = buf.str();
labelFrom = labelFrom.substr(0, (banked ? 12 : 15) - (timer.mirrors ? 1 : 0));
labelFrom += (timer.mirrors ? "+" : "");
labelFrom = (labelFrom + " ").substr(0, banked ? 12 : 15);
buf.str(""); buf.str("");
if(!debugger.cartDebug().getLabel(buf, timer.to.addr, true)) if(!debugger.cartDebug().getLabel(buf, timer.to.addr, true))
buf << " $" << setw(4) << Base::HEX4 << timer.to.addr; buf << " $" << setw(4) << Base::HEX4 << timer.to.addr;
string labelTo = buf.str(); string labelTo = buf.str();
labelTo = labelTo.substr(0, (banked ? 12 : 15) - (timer.mirrors ? 1 : 0));
labelFrom = (labelFrom + " ").substr(0, banked ? 12 : 15); labelTo += (timer.mirrors ? "+" : "");
labelTo = (labelTo + " ").substr(0, banked ? 12 : 15); labelTo = (labelTo + " ").substr(0, banked ? 12 : 15);
if(showHeader) if(showHeader)
@ -613,8 +616,8 @@ void DebuggerParser::printTimer(uInt32 idx, bool showHeader)
if(banked) if(banked)
{ {
commandResult << "/" << setw(2) << setfill(' '); commandResult << "/" << setw(2) << setfill(' ');
if(timer.from.bank == TimerMap::ANY_BANK) if(timer.anyBank)
commandResult << "-"; commandResult << "*";
else else
commandResult << dec << static_cast<uInt16>(timer.from.bank); commandResult << dec << static_cast<uInt16>(timer.from.bank);
} }
@ -628,8 +631,8 @@ void DebuggerParser::printTimer(uInt32 idx, bool showHeader)
if(banked) if(banked)
{ {
commandResult << "/" << setw(2) << setfill(' '); commandResult << "/" << setw(2) << setfill(' ');
if(timer.to.bank == TimerMap::ANY_BANK) if(timer.anyBank)
commandResult << "-"; commandResult << "*";
else else
commandResult << dec << static_cast<uInt16>(timer.to.bank); commandResult << dec << static_cast<uInt16>(timer.to.bank);
} }
@ -2294,58 +2297,111 @@ void DebuggerParser::executeTia()
// "timer" // "timer"
void DebuggerParser::executeTimer() void DebuggerParser::executeTimer()
{ {
// Input variants:
// timer current address @ current bank
// timer + current address + mirrors @ current bank
// timer * current address @ any bank
// timer + * current address + mirrors @ any bank
// timer addr addr @ current bank
// timer addr + addr + mirrors @ current bank
// timer addr * addr @ any bank
// timer addr + * addr + mirrors @ any bank
// timer bank current address @ bank
// timer bank + current address + mirrors @ bank
// timer addr bank addr @ bank
// timer addr bank + addr + mirrors @ bank
// timer addr addr addr, addr @ current bank
// timer addr addr + addr, addr + mirrors @ current bank
// timer addr addr * addr, addr @ any bank
// timer addr addr + * addr, addr + mirrors @ any bank
// timer addr addr bank addr, addr @ bank
// timer addr addr bank bank addr, addr @ bank, bank
// timer addr addr bank bank + addr, addr + mirrors @ bank, bank
const uInt32 romBankCount = debugger.cartDebug().romBankCount(); const uInt32 romBankCount = debugger.cartDebug().romBankCount();
const bool banked = romBankCount > 1;
bool mirrors = (argCount >= 1 && argStrings[argCount - 1] == "+")
|| (argCount >= 2 && argStrings[argCount - 2] == "+");
bool anyBank = banked
&& ((argCount >= 1 && argStrings[argCount - 1] == "*")
|| (argCount >= 2 && argStrings[argCount - 2] == "*"));
if(argCount < 2) argCount -= ((mirrors ? 1 : 0) + (anyBank ? 1 : 0));
{ if(argCount > 4)
const uInt16 addr = !argCount ? debugger.cpuDebug().pc() : args[0];
const uInt8 bank = !argCount ? debugger.cartDebug().getBank(addr) : TimerMap::ANY_BANK;
const uInt32 idx = debugger.m6502().addTimer(addr, bank);
commandResult << "set timer " << dec << idx << " "
<< (debugger.m6502().getTimer(idx).isPartial ? "start" : "end");
if(!argCount)
commandResult << " at $" << Base::HEX4 << (addr & TimerMap::ADDRESS_MASK);
if(romBankCount > 1 && !argCount)
commandResult << " + mirrors in bank #" << std::dec << static_cast<int>(bank);
return;
}
else if(argCount > 4)
{ {
outputCommandError("too many arguments", myCommand); outputCommandError("too many arguments", myCommand);
return; return;
} }
// Detect if 2nd parameter is bank uInt32 numAddrs = 0, numBanks = 0;
if(argCount == 2 && args[0] >= 0x1000 && args[1] <= TimerMap::ANY_BANK) uInt16 addr[2];
uInt8 bank[2];
// set defaults:
addr[0] = debugger.cpuDebug().pc() ;
bank[0] = debugger.cartDebug().getBank(addr[0]);
for(uInt32 i = 0; i < argCount; ++i)
{ {
const uInt16 addr = args[0]; if(static_cast<uInt32>(args[i]) >= std::max(0x80u, romBankCount - 1))
const uInt8 bank = args[1];
if(bank >= romBankCount && bank != TimerMap::ANY_BANK)
{ {
commandResult << red("invalid bank"); if(numAddrs == 2)
return; {
outputCommandError("too many address arguments", myCommand);
return;
}
addr[numAddrs++] = args[i];
} }
const uInt32 idx = debugger.m6502().addTimer(addr, bank); else
commandResult << "set timer " << dec << idx << " " {
<< (debugger.m6502().getTimer(idx).isPartial ? "start" : "end"); if(anyBank || (numBanks == 1 && numAddrs < 2) || numBanks == 2)
return; {
outputCommandError("too many bank arguments", myCommand);
return;
}
if(static_cast<uInt32>(args[i]) >= romBankCount)
{
commandResult << red("invalid bank");
return;
}
bank[numBanks++] = args[i];
}
}
uInt32 idx;
if(numAddrs < 2)
{
idx = debugger.m6502().addTimer(addr[0], bank[0], mirrors, anyBank);
} }
else else
{ {
const uInt8 bankFrom = argCount >= 3 ? args[2] : TimerMap::ANY_BANK; idx = debugger.m6502().addTimer(addr[0], addr[1],
if(bankFrom >= romBankCount && bankFrom != TimerMap::ANY_BANK) bank[0], numBanks < 2 ? bank[0] : bank[1],
mirrors, anyBank);
}
const bool isPartial = debugger.m6502().getTimer(idx).isPartial;
if(numAddrs < 2 && !isPartial)
{
mirrors |= debugger.m6502().getTimer(idx).mirrors;
anyBank |= debugger.m6502().getTimer(idx).anyBank;
}
commandResult << "set timer " << Base::toString(idx)
<< (numAddrs < 2 ? (isPartial ? " start" : " end") : "")
<< " at $" << Base::HEX4 << addr[0];
if(numAddrs == 2)
commandResult << ", $" << Base::HEX4 << addr[1];
if(mirrors)
commandResult << " + mirrors";
if(banked)
{
if(anyBank)
commandResult << " in all banks";
else
{ {
commandResult << red("invalid bank"); commandResult << " in bank #" << std::dec << static_cast<int>(bank[0]);
return; if(numBanks == 2)
commandResult << ", #" << std::dec << static_cast<int>(bank[1]);
} }
const uInt8 bankTo = argCount == 4 ? args[3] : bankFrom;
if(bankTo >= romBankCount && bankTo != TimerMap::ANY_BANK)
{
commandResult << red("invalid bank");
return;
}
const uInt32 idx = debugger.m6502().addTimer(args[0], args[1], bankFrom, bankTo);
commandResult << "timer " << idx << " added";
} }
} }
@ -3637,10 +3693,11 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
{ {
"timer", "timer",
"Set a cycle counting timer from addresses xx to yy [banks aa bb]", "Set a cycle counting timer from addresses xx to yy [banks aa bb]",
"Example: timer, timer 1000, timer 3000 3100, timer f000 f800 1", "Example: timer, timer 1000 + *, timer f000 f800 1 +",
false, false,
true, true,
{ Parameters::ARG_WORD, Parameters::ARG_MULTI_BYTE }, { Parameters::ARG_LABEL, Parameters::ARG_LABEL, Parameters::ARG_LABEL,
Parameters::ARG_LABEL, Parameters::ARG_LABEL, Parameters::ARG_MULTI_BYTE },
std::mem_fn(&DebuggerParser::executeTimer) std::mem_fn(&DebuggerParser::executeTimer)
}, },

View File

@ -21,18 +21,34 @@
TODOs: TODOs:
x unordered_multimap (not required for just a few timers) x unordered_multimap (not required for just a few timers)
o 13 vs 16 bit, use ADDRESS_MASK & ANY_BANK, when??? o 13 vs 16 bit, use ADDRESS_MASK & ANY_BANK, when???
- never, unless the user defines * for the bank
o any bank
- never unless the user defines *
? timer line display in disassembly? (color, symbol,...?) ? timer line display in disassembly? (color, symbol,...?)
- keep original from and to addresses for label display
*/ */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TimerMap::add(const uInt16 fromAddr, const uInt16 toAddr, void TimerMap::toKey(TimerPoint& tp, bool mirrors, bool anyBank)
const uInt8 fromBank, const uInt8 toBank)
{ {
const TimerPoint tpFrom(fromAddr, fromBank); if(mirrors)
const TimerPoint tpTo(toAddr, toBank); tp.addr &= ADDRESS_MASK;
const Timer complete(tpFrom, tpTo); if(anyBank)
tp.bank = ANY_BANK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TimerMap::add(uInt16 fromAddr, uInt16 toAddr,
uInt8 fromBank, uInt8 toBank,
bool mirrors, bool anyBank)
{
TimerPoint tpFrom(fromAddr, fromBank);
TimerPoint tpTo(toAddr, toBank);
const Timer complete(tpFrom, tpTo, mirrors, anyBank);
myList.push_back(complete); myList.push_back(complete);
toKey(tpFrom, mirrors, anyBank);
toKey(tpTo, mirrors, anyBank);
myFromMap.insert(TimerPair(tpFrom, &myList.back())); myFromMap.insert(TimerPair(tpFrom, &myList.back()));
myToMap.insert(TimerPair(tpTo, &myList.back())); myToMap.insert(TimerPair(tpTo, &myList.back()));
@ -40,31 +56,61 @@ uInt32 TimerMap::add(const uInt16 fromAddr, const uInt16 toAddr,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TimerMap::add(const uInt16 addr, const uInt8 bank) uInt32 TimerMap::add(uInt16 addr, uInt8 bank, bool mirrors, bool anyBank)
{ {
const uInt32 idx = size() - 1; uInt32 idx = size() - 1;
uInt32 i = 0; // find first incomplete timer, if any
for(auto it = myList.begin(); it != myList.end(); ++it, ++i)
if(it->isPartial)
{
idx = i;
break;
}
const bool isPartialTimer = size() && get(idx).isPartial; const bool isPartialTimer = size() && get(idx).isPartial;
const TimerPoint tp(addr, bank); TimerPoint tp(addr, bank);
if(!isPartialTimer) if(!isPartialTimer)
{ {
const Timer partial(tp); // create a new timer:
const Timer tmNew(tp, mirrors, anyBank);
myList.push_back(partial); myList.push_back(tmNew);
toKey(tp, mirrors, anyBank);
myFromMap.insert(TimerPair(tp, &myList.back())); myFromMap.insert(TimerPair(tp, &myList.back()));
return size() - 1;
} }
else else
{ {
Timer& partial = myList[idx]; // complete a partial timer:
Timer& tmPartial = myList[idx];
TimerPoint tpFrom = tmPartial.from;
bool oldMirrors = tmPartial.mirrors;
bool oldAnyBank = tmPartial.anyBank;
partial.setTo(tp); tmPartial.setTo(tp, mirrors, anyBank);
myToMap.insert(TimerPair(tp, &partial)); toKey(tp, tmPartial.mirrors, tmPartial.anyBank);
myToMap.insert(TimerPair(tp, &tmPartial));
// update tp key in myFromMap for new mirrors & anyBank settings
// 1. find map entry using OLD tp key settings:
toKey(tpFrom, oldMirrors, oldAnyBank);
auto from = myFromMap.equal_range(tpFrom);
for(auto it = from.first; it != from.second; ++it)
if(it->second == &tmPartial)
{
// 2. erase old map entry
myFromMap.erase(it);
// ...and add new map entry with NEW tp key settings:
toKey(tpFrom, tmPartial.mirrors, tmPartial.anyBank);
myFromMap.insert(TimerPair(tpFrom, &tmPartial));
break;
}
return idx;
} }
return size() - 1;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TimerMap::erase(const uInt32 idx) bool TimerMap::erase(uInt32 idx)
{ {
if(size() > idx) if(size() > idx)
{ {
@ -112,13 +158,12 @@ void TimerMap::reset()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimerMap::update(const uInt16 addr, const uInt8 bank, void TimerMap::update(uInt16 addr, uInt8 bank, const uInt64 cycles)
const uInt64 cycles)
{ {
// 13 bit timerpoint
if((addr & ADDRESS_MASK) != addr) if((addr & ADDRESS_MASK) != addr)
{ {
TimerPoint tp(addr, bank); // -> addr & ADDRESS_MASK // 13 bit timerpoint
TimerPoint tp(addr & ADDRESS_MASK, bank);
// Find address in from and to maps // Find address in from and to maps
const auto from = myFromMap.equal_range(tp); const auto from = myFromMap.equal_range(tp);
@ -133,7 +178,7 @@ void TimerMap::update(const uInt16 addr, const uInt8 bank,
} }
// 16 bit timerpoint // 16 bit timerpoint
TimerPoint tp(addr, bank, false); // -> addr TimerPoint tp(addr, bank);
// Find address in from and to maps // Find address in from and to maps
const auto from = myFromMap.equal_range(tp); const auto from = myFromMap.equal_range(tp);

View File

@ -32,11 +32,9 @@
*/ */
class TimerMap class TimerMap
{ {
public: private:
static constexpr uInt8 ANY_BANK = 255; // timer breakpoint valid in any bank
//private:
static constexpr uInt16 ADDRESS_MASK = 0x1fff; // either 0x1fff or 0xffff (not needed then) static constexpr uInt16 ADDRESS_MASK = 0x1fff; // either 0x1fff or 0xffff (not needed then)
static constexpr uInt8 ANY_BANK = 255; // timer point valid in any bank
private: private:
struct TimerPoint struct TimerPoint
@ -44,12 +42,9 @@ class TimerMap
uInt16 addr{0}; uInt16 addr{0};
uInt8 bank{ANY_BANK}; uInt8 bank{ANY_BANK};
explicit constexpr TimerPoint(uInt16 c_addr, uInt8 c_bank, bool mask = true) explicit constexpr TimerPoint(uInt16 c_addr, uInt8 c_bank)
: addr{c_addr}, bank{c_bank} : addr{c_addr}, bank{c_bank} {}
{
if(mask && bank != ANY_BANK)
addr = addr & ADDRESS_MASK;
}
TimerPoint() TimerPoint()
: addr{0}, bank(ANY_BANK) {} : addr{0}, bank(ANY_BANK) {}
@ -81,6 +76,8 @@ class TimerMap
{ {
TimerPoint from{}; TimerPoint from{};
TimerPoint to{}; TimerPoint to{};
bool mirrors{false};
bool anyBank{false};
bool isPartial{false}; bool isPartial{false};
uInt64 execs{0}; uInt64 execs{0};
@ -90,46 +87,28 @@ class TimerMap
uInt64 maxCycles{0}; uInt64 maxCycles{0};
bool isStarted{false}; bool isStarted{false};
explicit constexpr Timer(const TimerPoint& c_from, const TimerPoint& c_to) explicit constexpr Timer(const TimerPoint& c_from, const TimerPoint& c_to,
: from{c_from}, to{c_to} bool c_mirrors = false, bool c_anyBank = false)
: from{c_from}, to{c_to}, mirrors{c_mirrors}, anyBank{c_anyBank} {}
Timer(uInt16 fromAddr, uInt16 toAddr, uInt8 fromBank, uInt8 toBank,
bool mirrors = false, bool anyBank = false)
{ {
//if(to.bank == ANY_BANK) // TODO: check if this is required Timer(TimerPoint(fromAddr, fromBank), TimerPoint(fromAddr, fromBank),
//{ mirrors, anyBank);
// to.bank = from.bank;
// if(to.bank != ANY_BANK)
// to.addr &= ADDRESS_MASK;
//}
} }
Timer(uInt16 fromAddr, uInt16 toAddr, uInt8 fromBank, uInt8 toBank) Timer(const TimerPoint& tp, bool c_mirrors = false, bool c_anyBank = false)
{ {
Timer(TimerPoint(fromAddr, fromBank), TimerPoint(fromAddr, fromBank)); from = tp;
mirrors = c_mirrors;
anyBank = c_anyBank;
isPartial = true;
} }
Timer(const TimerPoint& tp) Timer(uInt16 addr, uInt8 bank, bool mirrors = false, bool anyBank = false)
{ {
if(!isPartial) Timer(TimerPoint(addr, bank), mirrors, anyBank);
{
from = tp;
isPartial = true;
}
else
{
to = tp;
isPartial = false;
//if(to.bank == ANY_BANK) // TODO: check if this is required
//{
// to.bank = from.bank;
// if(to.bank != ANY_BANK)
// to.addr &= ADDRESS_MASK;
//}
}
}
Timer(uInt16 addr, uInt8 bank)
{
Timer(TimerPoint(addr, bank));
} }
#if 0 // unused #if 0 // unused
@ -159,17 +138,12 @@ class TimerMap
} }
#endif #endif
void setTo(const TimerPoint& tp) void setTo(const TimerPoint& tp, bool c_mirrors = false, bool c_anyBank = false)
{ {
to = tp; to = tp;
mirrors |= c_mirrors;
anyBank |= c_anyBank;
isPartial = false; isPartial = false;
//if(to.bank == ANY_BANK) // TODO: check if this is required
//{
// to.bank = from.bank;
// if(to.bank != ANY_BANK)
// to.addr &= ADDRESS_MASK;
//}
} }
void reset() void reset()
@ -209,9 +183,11 @@ class TimerMap
bool isInitialized() const { return myList.size(); } bool isInitialized() const { return myList.size(); }
/** Add new timer */ /** Add new timer */
uInt32 add(const uInt16 fromAddr, const uInt16 toAddr, uInt32 add(uInt16 fromAddr, uInt16 toAddr,
const uInt8 fromBank, const uInt8 toBank); uInt8 fromBank, uInt8 toBank,
uInt32 add(const uInt16 addr, const uInt8 bank); bool mirrors, bool anyBank);
uInt32 add(uInt16 addr, uInt8 bank,
bool mirrors, bool anyBank);
/** Erase timer */ /** Erase timer */
bool erase(const uInt32 idx); bool erase(const uInt32 idx);
@ -223,13 +199,16 @@ class TimerMap
void reset(); void reset();
/** Get timer */ /** Get timer */
const Timer& get(const uInt32 idx) const { return myList[idx]; } const Timer& get(uInt32 idx) const { return myList[idx]; }
uInt32 size() const { return static_cast<uInt32>(myList.size()); } uInt32 size() const { return static_cast<uInt32>(myList.size()); }
/** Update timer */ /** Update timer */
void update(const uInt16 addr, const uInt8 bank, void update(uInt16 addr, uInt8 bank,
const uInt64 cycles); const uInt64 cycles);
private:
void toKey(TimerPoint& tp, bool mirrors, bool anyBank);
private: private:
using TimerList = std::deque<Timer>; // makes sure that the element pointers do NOT change using TimerList = std::deque<Timer>; // makes sure that the element pointers do NOT change
using TimerPair = std::pair<TimerPoint, Timer*>; using TimerPair = std::pair<TimerPoint, Timer*>;

View File

@ -698,20 +698,22 @@ void M6502::updateStepStateByInstruction()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 M6502::addTimer(const uInt16 fromAddr, const uInt16 toAddr, uInt32 M6502::addTimer(uInt16 fromAddr, uInt16 toAddr,
const uInt8 fromBank, const uInt8 toBank) uInt8 fromBank, uInt8 toBank,
bool mirrors, bool anyBank)
{ {
return myTimer.add(fromAddr, toAddr, fromBank, toBank); return myTimer.add(fromAddr, toAddr, fromBank, toBank, mirrors, anyBank);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 M6502::addTimer(const uInt16 addr, const uInt8 bank) uInt32 M6502::addTimer(uInt16 addr, uInt8 bank,
bool mirrors, bool anyBank)
{ {
return myTimer.add(addr, bank); return myTimer.add(addr, bank, mirrors, anyBank);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool M6502::delTimer(const uInt32 idx) bool M6502::delTimer(uInt32 idx)
{ {
return myTimer.erase(idx); return myTimer.erase(idx);
} }

View File

@ -254,9 +254,9 @@ class M6502 : public Serializable
const StringList& getCondTrapNames() const; const StringList& getCondTrapNames() const;
// methods for 'timer' handling: // methods for 'timer' handling:
uInt32 addTimer(uInt16 fromAddr, uInt16 toAddr, uInt32 addTimer(uInt16 fromAddr, uInt16 toAddr, uInt8 fromBank, uInt8 toBank,
uInt8 fromBank, uInt8 toBank); bool mirrors, bool anyBank);
uInt32 addTimer(uInt16 addr, uInt8 bank); uInt32 addTimer(uInt16 addr, uInt8 bank, bool mirrors, bool anyBank);
bool delTimer(uInt32 idx); bool delTimer(uInt32 idx);
void clearTimers(); void clearTimers();
void resetTimers(); void resetTimers();

View File

@ -97,7 +97,11 @@ void RomImageWidget::parseProperties(const FSNode& node, bool full)
// Create navigation surface // Create navigation surface
myNavSurface = instance().frameBuffer().allocateSurface( myNavSurface = instance().frameBuffer().allocateSurface(
_w, myImageHeight); _w, myImageHeight);
myNavSurface->setDstRect(Common::Rect(_x, _y, _x + _w, _y + myImageHeight));
const uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
myNavSurface->setDstRect(
Common::Rect(_x * scale, _y * scale,
(_x + _w) * scale, (_y + myImageHeight) * scale));
FBSurface::Attributes& attr = myNavSurface->attributes(); FBSurface::Attributes& attr = myNavSurface->attributes();
@ -382,7 +386,6 @@ void RomImageWidget::drawWidget(bool hilite)
// the dialog surface position into account // the dialog surface position into account
const Common::Rect& s_dst = s.dstRect(); const Common::Rect& s_dst = s.dstRect();
mySurface->setDstPos(x + s_dst.x(), y + s_dst.y()); mySurface->setDstPos(x + s_dst.x(), y + s_dst.y());
} }
else if(!mySurfaceErrorMsg.empty()) else if(!mySurfaceErrorMsg.empty())
{ {