mirror of https://github.com/stella-emu/stella.git
Fixed TIA image in debugger being two frames behind.
This commit is contained in:
parent
25e96c3164
commit
79d8ed0010
|
@ -70,7 +70,8 @@
|
||||||
|
|
||||||
* Fixed bug in debugger tracing and displaying the partial TIA image;
|
* Fixed bug in debugger tracing and displaying the partial TIA image;
|
||||||
the first time entering the debugger and starting to trace, the 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
|
* 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
|
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.
|
This fixes issues with a newer ZLIB not working with an older PNG, etc.
|
||||||
|
|
||||||
* Updated build scripts for Visual Studio 2017 (Windows) and MacOS
|
* 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+
|
* Updated UNIX configure script to work with the clang 5+ and gcc 7+
|
||||||
compiler versions, and fixed compile issues on AArch64 and ppc64le
|
compiler versions, and fixed compile issues on AArch64 and ppc64le
|
||||||
|
|
|
@ -169,7 +169,5 @@ void TiaOutputWidget::drawWidget(bool hilite)
|
||||||
|
|
||||||
// Show electron beam position
|
// Show electron beam position
|
||||||
if(visible && scanx < width && scany+2u < height)
|
if(visible && scanx < width && scany+2u < height)
|
||||||
{
|
|
||||||
s.fillRect(_x+(scanx<<1), _y+scany, 3, 3, kBtnTextColor);
|
s.fillRect(_x+(scanx<<1), _y+scany, 3, 3, kBtnTextColor);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ void TiaZoomWidget::drawWidget(bool hilite)
|
||||||
// Draw the zoomed image
|
// Draw the zoomed image
|
||||||
// This probably isn't as efficient as it can be, but it's a small area
|
// 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 :)
|
// 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(),
|
const int width = instance().console().tia().width(),
|
||||||
wzoom = myZoomLevel << 1,
|
wzoom = myZoomLevel << 1,
|
||||||
hzoom = myZoomLevel;
|
hzoom = myZoomLevel;
|
||||||
|
|
|
@ -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();
|
uInt32 tiaw = myTIA->width(), width = tiaw*2, height = myTIA->height();
|
||||||
rect.setBounds(0, 0, width, 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
|
uInt32 TIASurface::pixel(uInt32 idx, uInt8 shift) const
|
||||||
{
|
{
|
||||||
uInt8 c = *(myTIA->currentFrameBuffer() + idx) | shift;
|
// FIXME - use TJ phosphor code
|
||||||
uInt8 p = *(myTIA->previousFrameBuffer() + idx) | shift;
|
return myPalette[*(myTIA->frameBuffer() + idx) | shift];
|
||||||
|
|
||||||
return (!myUsePhosphor ? myPalette[c] : myPhosphorPalette[c][p]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -303,10 +301,9 @@ void TIASurface::render()
|
||||||
// In hardware rendering mode, it's faster to just assume that the screen
|
// In hardware rendering mode, it's faster to just assume that the screen
|
||||||
// is dirty and always do an update
|
// is dirty and always do an update
|
||||||
|
|
||||||
uInt8* currentFrame = myTIA->currentFrameBuffer();
|
uInt8* fbuffer = myTIA->frameBuffer();
|
||||||
uInt8* previousFrame = myTIA->previousFrameBuffer();
|
uInt32 width = myTIA->width();
|
||||||
uInt32 width = myTIA->width();
|
uInt32 height = myTIA->height();
|
||||||
uInt32 height = myTIA->height();
|
|
||||||
|
|
||||||
uInt32 *buffer, pitch;
|
uInt32 *buffer, pitch;
|
||||||
myTiaSurface->basePtr(buffer, pitch);
|
myTiaSurface->basePtr(buffer, pitch);
|
||||||
|
@ -323,7 +320,7 @@ void TIASurface::render()
|
||||||
{
|
{
|
||||||
uInt32 pos = screenofsY;
|
uInt32 pos = screenofsY;
|
||||||
for(uInt32 x = 0; x < width; ++x)
|
for(uInt32 x = 0; x < width; ++x)
|
||||||
buffer[pos++] = myPalette[currentFrame[bufofsY + x]];
|
buffer[pos++] = myPalette[fbuffer[bufofsY + x]];
|
||||||
|
|
||||||
bufofsY += width;
|
bufofsY += width;
|
||||||
screenofsY += pitch;
|
screenofsY += pitch;
|
||||||
|
@ -332,6 +329,7 @@ void TIASurface::render()
|
||||||
}
|
}
|
||||||
case kPhosphor:
|
case kPhosphor:
|
||||||
{
|
{
|
||||||
|
#if 0 // FIXME
|
||||||
uInt32 bufofsY = 0;
|
uInt32 bufofsY = 0;
|
||||||
uInt32 screenofsY = 0;
|
uInt32 screenofsY = 0;
|
||||||
for(uInt32 y = 0; y < height; ++y)
|
for(uInt32 y = 0; y < height; ++y)
|
||||||
|
@ -345,18 +343,20 @@ void TIASurface::render()
|
||||||
bufofsY += width;
|
bufofsY += width;
|
||||||
screenofsY += pitch;
|
screenofsY += pitch;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kBlarggNormal:
|
case kBlarggNormal:
|
||||||
{
|
{
|
||||||
myNTSCFilter.blit_single(currentFrame, width, height,
|
myNTSCFilter.blit_single(fbuffer, width, height, buffer, pitch << 2);
|
||||||
buffer, pitch << 2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kBlarggPhosphor:
|
case kBlarggPhosphor:
|
||||||
{
|
{
|
||||||
|
#if 0 // FIXME
|
||||||
myNTSCFilter.blit_double(currentFrame, previousFrame, width, height,
|
myNTSCFilter.blit_double(currentFrame, previousFrame, width, height,
|
||||||
buffer, pitch << 2);
|
buffer, pitch << 2);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ class TIASurface
|
||||||
/**
|
/**
|
||||||
Get the TIA base surface for use in saving to a PNG image.
|
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,
|
Get the TIA pixel associated with the given TIA buffer index,
|
||||||
|
|
|
@ -85,8 +85,7 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
myCurrentFrameBuffer = make_ptr<uInt8[]>(160 * FrameManager::frameBufferHeight);
|
myFramebuffer = make_ptr<uInt8[]>(160 * FrameManager::frameBufferHeight);
|
||||||
myPreviousFrameBuffer = make_ptr<uInt8[]>(160 * FrameManager::frameBufferHeight);
|
|
||||||
|
|
||||||
myTIAPinsDriven = mySettings.getBool("tiadriven");
|
myTIAPinsDriven = mySettings.getBool("tiadriven");
|
||||||
|
|
||||||
|
@ -152,7 +151,7 @@ void TIA::reset()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TIA::frameReset()
|
void TIA::frameReset()
|
||||||
{
|
{
|
||||||
clearBuffers();
|
memset(myFramebuffer.get(), 0, 160 * FrameManager::frameBufferHeight);
|
||||||
myAutoFrameEnabled = mySettings.getInt("framerate") <= 0;
|
myAutoFrameEnabled = mySettings.getInt("framerate") <= 0;
|
||||||
enableColorLoss(mySettings.getBool("colorloss"));
|
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
|
bool TIA::save(Serializer& out) const
|
||||||
{
|
{
|
||||||
|
@ -715,7 +707,7 @@ bool TIA::saveDisplay(Serializer& out) const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putByteArray(myCurrentFrameBuffer.get(), 160*320);
|
out.putByteArray(myFramebuffer.get(), 160*FrameManager::frameBufferHeight);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -732,9 +724,7 @@ bool TIA::loadDisplay(Serializer& in)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Reset frame buffer pointer and data
|
// Reset frame buffer pointer and data
|
||||||
clearBuffers();
|
in.getByteArray(myFramebuffer.get(), 160*FrameManager::frameBufferHeight);
|
||||||
in.getByteArray(myCurrentFrameBuffer.get(), 160*320);
|
|
||||||
memcpy(myPreviousFrameBuffer.get(), myCurrentFrameBuffer.get(), 160*320);
|
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -991,21 +981,13 @@ void TIA::updateEmulation()
|
||||||
cycle(cyclesToRun);
|
cycle(cyclesToRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void TIA::swapBuffers()
|
|
||||||
{
|
|
||||||
myCurrentFrameBuffer.swap(myPreviousFrameBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TIA::onFrameStart()
|
void TIA::onFrameStart()
|
||||||
{
|
{
|
||||||
swapBuffers();
|
|
||||||
|
|
||||||
const Int32 x = myHctr - 68;
|
const Int32 x = myHctr - 68;
|
||||||
|
|
||||||
if (x > 0)
|
if (x > 0)
|
||||||
memset(myCurrentFrameBuffer.get(), 0, x);
|
memset(myFramebuffer.get(), 0, x);
|
||||||
|
|
||||||
for (uInt8 i = 0; i < 4; i++)
|
for (uInt8 i = 0; i < 4; i++)
|
||||||
updatePaddle(i);
|
updatePaddle(i);
|
||||||
|
@ -1039,7 +1021,7 @@ void TIA::onFrameComplete()
|
||||||
// Blank out any extra lines not drawn this frame
|
// Blank out any extra lines not drawn this frame
|
||||||
const uInt32 missingScanlines = myFrameManager.missingScanlines();
|
const uInt32 missingScanlines = myFrameManager.missingScanlines();
|
||||||
if (missingScanlines > 0)
|
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'
|
// Recalculate framerate, attempting to auto-correct for scanline 'jumps'
|
||||||
if(myAutoFrameEnabled)
|
if(myAutoFrameEnabled)
|
||||||
|
@ -1142,7 +1124,7 @@ void TIA::applyRsync()
|
||||||
|
|
||||||
myXDelta = 157 - x;
|
myXDelta = 157 - x;
|
||||||
if (myFrameManager.isRendering())
|
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;
|
myHctr = 225;
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1158,7 @@ void TIA::cloneLastLine()
|
||||||
|
|
||||||
if (!myFrameManager.isRendering() || y == 0) return;
|
if (!myFrameManager.isRendering() || y == 0) return;
|
||||||
|
|
||||||
uInt8* buffer = myCurrentFrameBuffer.get();
|
uInt8* buffer = myFramebuffer.get();
|
||||||
|
|
||||||
memcpy(buffer + y * 160, buffer + (y-1) * 160, 160);
|
memcpy(buffer + y * 160, buffer + (y-1) * 160, 160);
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1225,7 @@ void TIA::renderPixel(uInt32 x, uInt32 y)
|
||||||
break;
|
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()
|
void TIA::clearHmoveComb()
|
||||||
{
|
{
|
||||||
if (myFrameManager.isRendering() && myHstate == HState::blank)
|
if (myFrameManager.isRendering() && myHstate == HState::blank)
|
||||||
memset(myCurrentFrameBuffer.get() + myFrameManager.getY() * 160,
|
memset(myFramebuffer.get() + myFrameManager.getY() * 160,
|
||||||
myColorHBlank, 8);
|
myColorHBlank, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,12 +76,12 @@ class TIA : public Device
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Reset device to its power-on state
|
Reset device to its power-on state.
|
||||||
*/
|
*/
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reset frame to current YStart/Height properties
|
Reset frame to current YStart/Height properties.
|
||||||
*/
|
*/
|
||||||
void frameReset();
|
void frameReset();
|
||||||
|
|
||||||
|
@ -100,14 +100,14 @@ class TIA : public Device
|
||||||
void install(System& system) override;
|
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
|
@return The byte at the specified address
|
||||||
*/
|
*/
|
||||||
uInt8 peek(uInt16 address) override;
|
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 address The address where the value should be stored
|
||||||
@param value The value to be stored at the address
|
@param value The value to be stored at the address
|
||||||
|
@ -157,13 +157,12 @@ class TIA : public Device
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Answers the current and previous frame buffer pointers
|
Returns pointer to the internal frame buffer.
|
||||||
*/
|
*/
|
||||||
uInt8* currentFrameBuffer() const { return myCurrentFrameBuffer.get(); }
|
uInt8* frameBuffer() const { return myFramebuffer.get(); }
|
||||||
uInt8* previousFrameBuffer() const { return myPreviousFrameBuffer.get(); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Answers dimensional info about the framebuffer
|
Answers dimensional info about the framebuffer.
|
||||||
*/
|
*/
|
||||||
uInt32 width() const { return 160; }
|
uInt32 width() const { return 160; }
|
||||||
uInt32 height() const { return myFrameManager.height(); }
|
uInt32 height() const { return myFrameManager.height(); }
|
||||||
|
@ -305,9 +304,6 @@ class TIA : public Device
|
||||||
bool toggleJitter(uInt8 mode = 2);
|
bool toggleJitter(uInt8 mode = 2);
|
||||||
void setJitterRecoveryFactor(Int32 factor) { myFrameManager.setJitterFactor(factor); }
|
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.
|
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);
|
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;
|
uInt8 registerValue(uInt8 reg) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the current x value
|
Get the current x value.
|
||||||
*/
|
*/
|
||||||
uInt8 getPosition() const {
|
uInt8 getPosition() const {
|
||||||
return (myHctr < 68) ? 0 : (myHctr - 68 - myXDelta);
|
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
|
Flush the line cache after an externally triggered state change
|
||||||
(e.g. a register write)
|
(e.g. a register write).
|
||||||
*/
|
*/
|
||||||
void flushLineCache();
|
void flushLineCache();
|
||||||
|
|
||||||
|
@ -431,8 +427,6 @@ class TIA : public Device
|
||||||
|
|
||||||
uInt8 resxCounter();
|
uInt8 resxCounter();
|
||||||
|
|
||||||
void swapBuffers();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the result of the specified collision register.
|
Get the result of the specified collision register.
|
||||||
*/
|
*/
|
||||||
|
@ -469,9 +463,8 @@ class TIA : public Device
|
||||||
LatchedInput myInput0;
|
LatchedInput myInput0;
|
||||||
LatchedInput myInput1;
|
LatchedInput myInput1;
|
||||||
|
|
||||||
// Pointer to the current and previous frame buffers
|
// Pointer to the internal frame buffer
|
||||||
BytePtr myCurrentFrameBuffer;
|
BytePtr myFramebuffer;
|
||||||
BytePtr myPreviousFrameBuffer;
|
|
||||||
|
|
||||||
bool myTIAPinsDriven;
|
bool myTIAPinsDriven;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue