Fixed TIA image in debugger being two frames behind.

This commit is contained in:
Stephen Anthony 2017-05-28 13:55:23 -02:30
parent 25e96c3164
commit 79d8ed0010
7 changed files with 40 additions and 65 deletions

View File

@ -70,7 +70,8 @@
* Fixed bug in debugger tracing and displaying the partial TIA image;
the first time entering the debugger and starting to trace, the image
was blanked out (black) instead of being drawn in greyscale.
was blanked out (black) instead of being drawn in greyscale. Also, the
image is now synchronized, instead of being two frames behind.
* Fixed crash with zipped ROMs that are less than 4K in size; so far
this bug has only ever occurred in Windows XP, but it's been there
@ -124,7 +125,8 @@
This fixes issues with a newer ZLIB not working with an older PNG, etc.
* Updated build scripts for Visual Studio 2017 (Windows) and MacOS
Sierra (latest version of Xcode).
Sierra (latest version of Xcode), and make these the minimum supported
versions.
* Updated UNIX configure script to work with the clang 5+ and gcc 7+
compiler versions, and fixed compile issues on AArch64 and ppc64le

View File

@ -169,7 +169,5 @@ void TiaOutputWidget::drawWidget(bool hilite)
// Show electron beam position
if(visible && scanx < width && scany+2u < height)
{
s.fillRect(_x+(scanx<<1), _y+scany, 3, 3, kBtnTextColor);
}
}

View File

@ -246,7 +246,7 @@ void TiaZoomWidget::drawWidget(bool hilite)
// Draw the zoomed image
// This probably isn't as efficient as it can be, but it's a small area
// and I don't have time to make it faster :)
const uInt8* currentFrame = instance().console().tia().currentFrameBuffer();
const uInt8* currentFrame = instance().console().tia().frameBuffer();
const int width = instance().console().tia().width(),
wzoom = myZoomLevel << 1,
hzoom = myZoomLevel;

View File

@ -121,7 +121,7 @@ void TIASurface::setPalette(const uInt32* tia_palette, const uInt32* rgb_palette
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const FBSurface& TIASurface::baseSurface(GUI::Rect& rect)
const FBSurface& TIASurface::baseSurface(GUI::Rect& rect) const
{
uInt32 tiaw = myTIA->width(), width = tiaw*2, height = myTIA->height();
rect.setBounds(0, 0, width, height);
@ -146,10 +146,8 @@ const FBSurface& TIASurface::baseSurface(GUI::Rect& rect)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIASurface::pixel(uInt32 idx, uInt8 shift) const
{
uInt8 c = *(myTIA->currentFrameBuffer() + idx) | shift;
uInt8 p = *(myTIA->previousFrameBuffer() + idx) | shift;
return (!myUsePhosphor ? myPalette[c] : myPhosphorPalette[c][p]);
// FIXME - use TJ phosphor code
return myPalette[*(myTIA->frameBuffer() + idx) | shift];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -303,8 +301,7 @@ void TIASurface::render()
// In hardware rendering mode, it's faster to just assume that the screen
// is dirty and always do an update
uInt8* currentFrame = myTIA->currentFrameBuffer();
uInt8* previousFrame = myTIA->previousFrameBuffer();
uInt8* fbuffer = myTIA->frameBuffer();
uInt32 width = myTIA->width();
uInt32 height = myTIA->height();
@ -323,7 +320,7 @@ void TIASurface::render()
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x)
buffer[pos++] = myPalette[currentFrame[bufofsY + x]];
buffer[pos++] = myPalette[fbuffer[bufofsY + x]];
bufofsY += width;
screenofsY += pitch;
@ -332,6 +329,7 @@ void TIASurface::render()
}
case kPhosphor:
{
#if 0 // FIXME
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y)
@ -345,18 +343,20 @@ void TIASurface::render()
bufofsY += width;
screenofsY += pitch;
}
#endif
break;
}
case kBlarggNormal:
{
myNTSCFilter.blit_single(currentFrame, width, height,
buffer, pitch << 2);
myNTSCFilter.blit_single(fbuffer, width, height, buffer, pitch << 2);
break;
}
case kBlarggPhosphor:
{
#if 0 // FIXME
myNTSCFilter.blit_double(currentFrame, previousFrame, width, height,
buffer, pitch << 2);
#endif
break;
}
}

View File

@ -67,7 +67,7 @@ class TIASurface
/**
Get the TIA base surface for use in saving to a PNG image.
*/
const FBSurface& baseSurface(GUI::Rect& rect);
const FBSurface& baseSurface(GUI::Rect& rect) const;
/**
Get the TIA pixel associated with the given TIA buffer index,

View File

@ -85,8 +85,7 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
}
);
myCurrentFrameBuffer = make_ptr<uInt8[]>(160 * FrameManager::frameBufferHeight);
myPreviousFrameBuffer = make_ptr<uInt8[]>(160 * FrameManager::frameBufferHeight);
myFramebuffer = make_ptr<uInt8[]>(160 * FrameManager::frameBufferHeight);
myTIAPinsDriven = mySettings.getBool("tiadriven");
@ -152,7 +151,7 @@ void TIA::reset()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::frameReset()
{
clearBuffers();
memset(myFramebuffer.get(), 0, 160 * FrameManager::frameBufferHeight);
myAutoFrameEnabled = mySettings.getInt("framerate") <= 0;
enableColorLoss(mySettings.getBool("colorloss"));
}
@ -194,13 +193,6 @@ void TIA::installDelegate(System& system, Device& device)
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::clearBuffers()
{
memset(myCurrentFrameBuffer.get(), 0, 160 * FrameManager::frameBufferHeight);
memset(myPreviousFrameBuffer.get(), 0, 160 * FrameManager::frameBufferHeight);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIA::save(Serializer& out) const
{
@ -715,7 +707,7 @@ bool TIA::saveDisplay(Serializer& out) const
{
try
{
out.putByteArray(myCurrentFrameBuffer.get(), 160*320);
out.putByteArray(myFramebuffer.get(), 160*FrameManager::frameBufferHeight);
}
catch(...)
{
@ -732,9 +724,7 @@ bool TIA::loadDisplay(Serializer& in)
try
{
// Reset frame buffer pointer and data
clearBuffers();
in.getByteArray(myCurrentFrameBuffer.get(), 160*320);
memcpy(myPreviousFrameBuffer.get(), myCurrentFrameBuffer.get(), 160*320);
in.getByteArray(myFramebuffer.get(), 160*FrameManager::frameBufferHeight);
}
catch(...)
{
@ -991,21 +981,13 @@ void TIA::updateEmulation()
cycle(cyclesToRun);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::swapBuffers()
{
myCurrentFrameBuffer.swap(myPreviousFrameBuffer);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::onFrameStart()
{
swapBuffers();
const Int32 x = myHctr - 68;
if (x > 0)
memset(myCurrentFrameBuffer.get(), 0, x);
memset(myFramebuffer.get(), 0, x);
for (uInt8 i = 0; i < 4; i++)
updatePaddle(i);
@ -1039,7 +1021,7 @@ void TIA::onFrameComplete()
// Blank out any extra lines not drawn this frame
const uInt32 missingScanlines = myFrameManager.missingScanlines();
if (missingScanlines > 0)
memset(myCurrentFrameBuffer.get() + 160 * myFrameManager.getY(), 0, missingScanlines * 160);
memset(myFramebuffer.get() + 160 * myFrameManager.getY(), 0, missingScanlines * 160);
// Recalculate framerate, attempting to auto-correct for scanline 'jumps'
if(myAutoFrameEnabled)
@ -1142,7 +1124,7 @@ void TIA::applyRsync()
myXDelta = 157 - x;
if (myFrameManager.isRendering())
memset(myCurrentFrameBuffer.get() + myFrameManager.getY() * 160 + x, 0, 160 - x);
memset(myFramebuffer.get() + myFrameManager.getY() * 160 + x, 0, 160 - x);
myHctr = 225;
}
@ -1176,7 +1158,7 @@ void TIA::cloneLastLine()
if (!myFrameManager.isRendering() || y == 0) return;
uInt8* buffer = myCurrentFrameBuffer.get();
uInt8* buffer = myFramebuffer.get();
memcpy(buffer + y * 160, buffer + (y-1) * 160, 160);
}
@ -1243,7 +1225,7 @@ void TIA::renderPixel(uInt32 x, uInt32 y)
break;
}
myCurrentFrameBuffer.get()[y * 160 + x] = myFrameManager.vblank() ? 0 : color;
myFramebuffer.get()[y * 160 + x] = myFrameManager.vblank() ? 0 : color;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1269,7 +1251,7 @@ void TIA::flushLineCache()
void TIA::clearHmoveComb()
{
if (myFrameManager.isRendering() && myHstate == HState::blank)
memset(myCurrentFrameBuffer.get() + myFrameManager.getY() * 160,
memset(myFramebuffer.get() + myFrameManager.getY() * 160,
myColorHBlank, 8);
}

View File

@ -76,12 +76,12 @@ class TIA : public Device
public:
/**
Reset device to its power-on state
Reset device to its power-on state.
*/
void reset() override;
/**
Reset frame to current YStart/Height properties
Reset frame to current YStart/Height properties.
*/
void frameReset();
@ -100,14 +100,14 @@ class TIA : public Device
void install(System& system) override;
/**
Get the byte at the specified address
Get the byte at the specified address.
@return The byte at the specified address
*/
uInt8 peek(uInt16 address) override;
/**
Change the byte at the specified address to the given value
Change the byte at the specified address to the given value.
@param address The address where the value should be stored
@param value The value to be stored at the address
@ -157,13 +157,12 @@ class TIA : public Device
void update();
/**
Answers the current and previous frame buffer pointers
Returns pointer to the internal frame buffer.
*/
uInt8* currentFrameBuffer() const { return myCurrentFrameBuffer.get(); }
uInt8* previousFrameBuffer() const { return myPreviousFrameBuffer.get(); }
uInt8* frameBuffer() const { return myFramebuffer.get(); }
/**
Answers dimensional info about the framebuffer
Answers dimensional info about the framebuffer.
*/
uInt32 width() const { return 160; }
uInt32 height() const { return myFrameManager.height(); }
@ -305,9 +304,6 @@ class TIA : public Device
bool toggleJitter(uInt8 mode = 2);
void setJitterRecoveryFactor(Int32 factor) { myFrameManager.setJitterFactor(factor); }
// Clear both internal TIA buffers to black (palette color 0)
void clearBuffers();
/**
This method should be called to update the TIA with a new scanline.
*/
@ -326,12 +322,12 @@ class TIA : public Device
TIA& updateScanlineByTrace(int target);
/**
Retrieve the last value written to a certain register
Retrieve the last value written to a certain register.
*/
uInt8 registerValue(uInt8 reg) const;
/**
Get the current x value
Get the current x value.
*/
uInt8 getPosition() const {
return (myHctr < 68) ? 0 : (myHctr - 68 - myXDelta);
@ -339,7 +335,7 @@ class TIA : public Device
/**
Flush the line cache after an externally triggered state change
(e.g. a register write)
(e.g. a register write).
*/
void flushLineCache();
@ -431,8 +427,6 @@ class TIA : public Device
uInt8 resxCounter();
void swapBuffers();
/**
Get the result of the specified collision register.
*/
@ -469,9 +463,8 @@ class TIA : public Device
LatchedInput myInput0;
LatchedInput myInput1;
// Pointer to the current and previous frame buffers
BytePtr myCurrentFrameBuffer;
BytePtr myPreviousFrameBuffer;
// Pointer to the internal frame buffer
BytePtr myFramebuffer;
bool myTIAPinsDriven;