Fixed issues with screenshots

This commit is contained in:
Souryo 2017-09-01 16:00:55 -04:00
parent b80d788346
commit 31502f6c16
7 changed files with 69 additions and 36 deletions

View file

@ -5,6 +5,7 @@
#include "../Utilities/FolderUtilities.h" #include "../Utilities/FolderUtilities.h"
#include "Console.h" #include "Console.h"
#include "StandardController.h" #include "StandardController.h"
#include "ScaleFilter.h"
BaseVideoFilter::BaseVideoFilter() BaseVideoFilter::BaseVideoFilter()
{ {
@ -60,28 +61,40 @@ uint8_t* BaseVideoFilter::GetOutputBuffer()
return _outputBuffer; return _outputBuffer;
} }
void BaseVideoFilter::TakeScreenshot(string filename, std::stringstream *stream) void BaseVideoFilter::TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream)
{ {
uint32_t* pngBuffer;
FrameInfo frameInfo;
uint32_t* frameBuffer = nullptr; uint32_t* frameBuffer = nullptr;
{ {
auto lock = _frameLock.AcquireSafe(); auto lock = _frameLock.AcquireSafe();
if(_bufferSize == 0 || !GetOutputBuffer()) { if(_bufferSize == 0 || !GetOutputBuffer()) {
return; return;
} }
frameBuffer = (uint32_t*)new uint8_t[_bufferSize]; frameBuffer = (uint32_t*)new uint8_t[_bufferSize];
memcpy(frameBuffer, GetOutputBuffer(), _bufferSize); memcpy(frameBuffer, GetOutputBuffer(), _bufferSize);
frameInfo = GetFrameInfo();
}
shared_ptr<ScaleFilter> scaleFilter = ScaleFilter::GetScaleFilter(filterType);
if(scaleFilter) {
pngBuffer = scaleFilter->ApplyFilter(frameBuffer, frameInfo.Width, frameInfo.Height);
frameInfo = scaleFilter->GetFrameInfo(frameInfo);
} else {
pngBuffer = frameBuffer;
} }
if(!filename.empty()) { if(!filename.empty()) {
PNGHelper::WritePNG(filename, frameBuffer, GetFrameInfo().Width, GetFrameInfo().Height); PNGHelper::WritePNG(filename, pngBuffer, frameInfo.Width, frameInfo.Height);
} else { } else {
PNGHelper::WritePNG(*stream, frameBuffer, GetFrameInfo().Width, GetFrameInfo().Height); PNGHelper::WritePNG(*stream, pngBuffer, frameInfo.Width, frameInfo.Height);
} }
delete[] frameBuffer; delete[] frameBuffer;
} }
void BaseVideoFilter::TakeScreenshot() void BaseVideoFilter::TakeScreenshot(VideoFilterType filterType)
{ {
string romFilename = FolderUtilities::GetFilename(Console::GetRomName(), false); string romFilename = FolderUtilities::GetFilename(Console::GetRomName(), false);
@ -103,7 +116,7 @@ void BaseVideoFilter::TakeScreenshot()
counter++; counter++;
} }
TakeScreenshot(ssFilename); TakeScreenshot(filterType, ssFilename);
MessageManager::DisplayMessage("ScreenshotSaved", FolderUtilities::GetFilename(ssFilename, true)); MessageManager::DisplayMessage("ScreenshotSaved", FolderUtilities::GetFilename(ssFilename, true));
} }

View file

@ -26,8 +26,8 @@ public:
uint8_t* GetOutputBuffer(); uint8_t* GetOutputBuffer();
void SendFrame(uint16_t *ppuOutputBuffer); void SendFrame(uint16_t *ppuOutputBuffer);
void TakeScreenshot(); void TakeScreenshot(VideoFilterType filterType);
void TakeScreenshot(string filename, std::stringstream *stream = nullptr); void TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream = nullptr);
virtual OverscanDimensions GetOverscan(); virtual OverscanDimensions GetOverscan();
virtual FrameInfo GetFrameInfo() = 0; virtual FrameInfo GetFrameInfo() = 0;

View file

@ -97,4 +97,43 @@ uint32_t* ScaleFilter::ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, ui
} }
return _outputBuffer; return _outputBuffer;
}
shared_ptr<ScaleFilter> ScaleFilter::GetScaleFilter(VideoFilterType filter)
{
shared_ptr<ScaleFilter> scaleFilter;
switch(filter) {
case VideoFilterType::xBRZ2x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 2)); break;
case VideoFilterType::xBRZ3x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 3)); break;
case VideoFilterType::xBRZ4x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 4)); break;
case VideoFilterType::xBRZ5x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 5)); break;
case VideoFilterType::xBRZ6x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 6)); break;
case VideoFilterType::HQ2x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 2)); break;
case VideoFilterType::HQ3x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 3)); break;
case VideoFilterType::HQ4x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 4)); break;
case VideoFilterType::Scale2x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 2)); break;
case VideoFilterType::Scale3x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 3)); break;
case VideoFilterType::Scale4x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 4)); break;
case VideoFilterType::_2xSai: scaleFilter.reset(new ScaleFilter(ScaleFilterType::_2xSai, 2)); break;
case VideoFilterType::Super2xSai: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Super2xSai, 2)); break;
case VideoFilterType::SuperEagle: scaleFilter.reset(new ScaleFilter(ScaleFilterType::SuperEagle, 2)); break;
case VideoFilterType::Prescale2x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 2)); break;
case VideoFilterType::Prescale3x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 3)); break;
case VideoFilterType::Prescale4x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 4)); break;
case VideoFilterType::Prescale6x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 6)); break;
case VideoFilterType::Prescale8x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 8)); break;
case VideoFilterType::Prescale10x: scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 10)); break;
}
return scaleFilter;
}
FrameInfo ScaleFilter::GetFrameInfo(FrameInfo baseFrameInfo)
{
FrameInfo info = baseFrameInfo;
info.Height *= this->GetScale();
info.Width *= this->GetScale();
info.OriginalHeight *= this->GetScale();
info.OriginalWidth *= this->GetScale();
return info;
} }

View file

@ -22,4 +22,7 @@ public:
uint32_t GetScale(); uint32_t GetScale();
uint32_t* ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, uint32_t height); uint32_t* ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, uint32_t height);
FrameInfo GetFrameInfo(FrameInfo baseFrameInfo);
static shared_ptr<ScaleFilter> GetScaleFilter(VideoFilterType filter);
}; };

View file

@ -72,31 +72,12 @@ void VideoDecoder::UpdateVideoFilter()
_scaleFilter.reset(); _scaleFilter.reset();
switch(_videoFilterType) { switch(_videoFilterType) {
case VideoFilterType::None: break;
case VideoFilterType::NTSC: _videoFilter.reset(new NtscFilter()); break; case VideoFilterType::NTSC: _videoFilter.reset(new NtscFilter()); break;
case VideoFilterType::BisqwitNtsc: _videoFilter.reset(new BisqwitNtscFilter(1)); break; case VideoFilterType::BisqwitNtsc: _videoFilter.reset(new BisqwitNtscFilter(1)); break;
case VideoFilterType::BisqwitNtscHalfRes: _videoFilter.reset(new BisqwitNtscFilter(2)); break; case VideoFilterType::BisqwitNtscHalfRes: _videoFilter.reset(new BisqwitNtscFilter(2)); break;
case VideoFilterType::BisqwitNtscQuarterRes: _videoFilter.reset(new BisqwitNtscFilter(4)); break; case VideoFilterType::BisqwitNtscQuarterRes: _videoFilter.reset(new BisqwitNtscFilter(4)); break;
case VideoFilterType::xBRZ2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 2)); break; default: _scaleFilter = ScaleFilter::GetScaleFilter(_videoFilterType); break;
case VideoFilterType::xBRZ3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 3)); break;
case VideoFilterType::xBRZ4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 4)); break;
case VideoFilterType::xBRZ5x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 5)); break;
case VideoFilterType::xBRZ6x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 6)); break;
case VideoFilterType::HQ2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 2)); break;
case VideoFilterType::HQ3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 3)); break;
case VideoFilterType::HQ4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 4)); break;
case VideoFilterType::Scale2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 2)); break;
case VideoFilterType::Scale3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 3)); break;
case VideoFilterType::Scale4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 4)); break;
case VideoFilterType::_2xSai: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::_2xSai, 2)); break;
case VideoFilterType::Super2xSai: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Super2xSai, 2)); break;
case VideoFilterType::SuperEagle: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::SuperEagle, 2)); break;
case VideoFilterType::Prescale2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 2)); break;
case VideoFilterType::Prescale3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 3)); break;
case VideoFilterType::Prescale4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 4)); break;
case VideoFilterType::Prescale6x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 6)); break;
case VideoFilterType::Prescale8x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 8)); break;
case VideoFilterType::Prescale10x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 10)); break;
} }
_hdFilterEnabled = false; _hdFilterEnabled = false;
@ -131,10 +112,7 @@ void VideoDecoder::DecodeFrame()
FrameInfo frameInfo = _videoFilter->GetFrameInfo(); FrameInfo frameInfo = _videoFilter->GetFrameInfo();
if(_scaleFilter) { if(_scaleFilter) {
frameInfo.Height *= _scaleFilter->GetScale(); frameInfo = _scaleFilter->GetFrameInfo(frameInfo);
frameInfo.Width *= _scaleFilter->GetScale();
frameInfo.OriginalHeight *= _scaleFilter->GetScale();
frameInfo.OriginalWidth *= _scaleFilter->GetScale();
} }
_frameChanged = false; _frameChanged = false;
@ -245,13 +223,13 @@ bool VideoDecoder::IsRunning()
void VideoDecoder::TakeScreenshot() void VideoDecoder::TakeScreenshot()
{ {
if(_videoFilter) { if(_videoFilter) {
_videoFilter->TakeScreenshot(); _videoFilter->TakeScreenshot(_videoFilterType);
} }
} }
void VideoDecoder::TakeScreenshot(std::stringstream &stream) void VideoDecoder::TakeScreenshot(std::stringstream &stream)
{ {
if(_videoFilter) { if(_videoFilter) {
_videoFilter->TakeScreenshot("", &stream); _videoFilter->TakeScreenshot(_videoFilterType, "", &stream);
} }
} }

View file

@ -42,7 +42,7 @@ private:
VideoFilterType _videoFilterType = VideoFilterType::None; VideoFilterType _videoFilterType = VideoFilterType::None;
unique_ptr<BaseVideoFilter> _videoFilter; unique_ptr<BaseVideoFilter> _videoFilter;
unique_ptr<ScaleFilter> _scaleFilter; shared_ptr<ScaleFilter> _scaleFilter;
void UpdateVideoFilter(); void UpdateVideoFilter();

View file

@ -10,7 +10,7 @@ bool PNGHelper::WritePNG(std::stringstream &stream, uint32_t* buffer, uint32_t x
//ARGB -> ABGR //ARGB -> ABGR
uint32_t size = xSize * ySize * bitsPerPixel / 8 / 4; uint32_t size = xSize * ySize * bitsPerPixel / 8 / 4;
for(uint32_t i = 0; i < size; i++) { for(uint32_t i = 0; i < size; i++) {
buffer[i] = (buffer[i] & 0xFF00FF00) | ((buffer[i] & 0xFF0000) >> 16) | ((buffer[i] & 0xFF) << 16); buffer[i] = 0xFF000000 | (buffer[i] & 0x00FF00) | ((buffer[i] & 0xFF0000) >> 16) | ((buffer[i] & 0xFF) << 16);
} }
void *pngData = tdefl_write_image_to_png_file_in_memory_ex(buffer, xSize, ySize, bitsPerPixel / 8, &pngSize, MZ_DEFAULT_LEVEL, MZ_FALSE); void *pngData = tdefl_write_image_to_png_file_in_memory_ex(buffer, xSize, ySize, bitsPerPixel / 8, &pngSize, MZ_DEFAULT_LEVEL, MZ_FALSE);