Debugger: Lua - Fixed some bugs/limitations with drawing routines (now works with NTSC filters, etc.)

This commit is contained in:
Sour 2018-03-24 09:48:45 -04:00
parent 59858bdd58
commit b641830058
10 changed files with 65 additions and 33 deletions

View file

@ -7,6 +7,7 @@
#include "StandardController.h"
#include "ScaleFilter.h"
#include "RotateFilter.h"
#include "DebugHud.h"
BaseVideoFilter::BaseVideoFilter()
{
@ -51,14 +52,17 @@ bool BaseVideoFilter::IsOddFrame()
return _isOddFrame;
}
void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer, bool isOddFrame)
void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer, uint32_t frameNumber)
{
_frameLock.Acquire();
_overscan = EmulationSettings::GetOverscanDimensions();
_isOddFrame = isOddFrame;
_isOddFrame = frameNumber % 2;
UpdateBufferSize();
OnBeforeApplyFilter();
ApplyFilter(ppuOutputBuffer);
if(DebugHud::GetInstance()) {
DebugHud::GetInstance()->Draw((uint32_t*)_outputBuffer, _overscan, GetFrameInfo().Width, frameNumber);
}
_frameLock.Release();
}

View file

@ -26,7 +26,7 @@ public:
virtual ~BaseVideoFilter();
uint8_t* GetOutputBuffer();
void SendFrame(uint16_t *ppuOutputBuffer, bool isOddFrame);
void SendFrame(uint16_t *ppuOutputBuffer, uint32_t frameNumber);
void TakeScreenshot(VideoFilterType filterType);
void TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream = nullptr);

View file

@ -35,11 +35,11 @@ void DebugHud::ClearScreen()
_commands.clear();
}
void DebugHud::Draw(uint32_t* argbBuffer, OverscanDimensions &overscan)
void DebugHud::Draw(uint32_t* argbBuffer, OverscanDimensions &overscan, uint32_t lineWidth, uint32_t frameNumber)
{
auto lock = _commandLock.AcquireSafe();
for(shared_ptr<DrawCommand> &command : _commands) {
command->Draw(argbBuffer, overscan);
command->Draw(argbBuffer, overscan, lineWidth, frameNumber);
}
_commands.erase(std::remove_if(_commands.begin(), _commands.end(), [](const shared_ptr<DrawCommand>& c) { return c->Expired(); }), _commands.end());
}

View file

@ -16,7 +16,7 @@ public:
DebugHud();
~DebugHud();
void Draw(uint32_t* argbBuffer, OverscanDimensions &overscan);
void Draw(uint32_t* argbBuffer, OverscanDimensions &overscan, uint32_t width, uint32_t frameNumber);
void ClearScreen();
void DrawPixel(int x, int y, int color, int frameCount);

View file

@ -71,10 +71,6 @@ void DefaultVideoFilter::DecodePpuBuffer(uint16_t *ppuOutputBuffer, uint32_t* ou
}
}
}
if(DebugHud::GetInstance()) {
DebugHud::GetInstance()->Draw(outputBuffer, overscan);
}
}
void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)

View file

@ -1,6 +1,7 @@
#pragma once
#include "stdafx.h"
#include "EmulationSettings.h"
#include "PPU.h"
class DrawCommand
{
@ -8,8 +9,14 @@ private:
int _frameCount;
uint32_t* _argbBuffer;
OverscanDimensions _overscan;
uint32_t _lineWidth;
uint32_t _startFrame;
protected:
bool _useIntegerScaling;
float _xScale;
int _yScale;
virtual void InternalDraw() = 0;
__forceinline void DrawPixel(uint32_t x, uint32_t y, int color)
{
@ -20,13 +27,30 @@ protected:
}
uint32_t alpha = (color & 0xFF000000);
if(alpha > 0) {
if(_yScale == 1) {
if(alpha != 0xFF000000) {
BlendColors((uint8_t*)&_argbBuffer[(y - _overscan.Top)*_lineWidth + (x - _overscan.Left)], (uint8_t*)&color);
} else {
_argbBuffer[(y - _overscan.Top)*_lineWidth + (x - _overscan.Left)] = color;
}
} else {
int xPixelCount = _useIntegerScaling ? _yScale : (int)((x + 1)*_xScale) - (int)(x*_xScale);
x = (int)(x * (_useIntegerScaling ? _yScale : _xScale));
y = (int)(y * _yScale);
int top = (int)(_overscan.Top * _yScale);
int left = (int)(_overscan.Left * _xScale);
if(alpha == 0) {
//do nothing
} else if(alpha != 0xFF000000) {
BlendColors((uint8_t*)&_argbBuffer[(y - _overscan.Top)*_overscan.GetScreenWidth() + (x - _overscan.Left)], (uint8_t*)&color);
} else {
_argbBuffer[(y - _overscan.Top)*_overscan.GetScreenWidth() + (x - _overscan.Left)] = color;
for(int i = 0; i < _yScale; i++) {
for(int j = 0; j < xPixelCount; j++) {
if(alpha != 0xFF000000) {
BlendColors((uint8_t*)&_argbBuffer[(y - top)*_lineWidth + i*_lineWidth + (x - left)+j], (uint8_t*)&color);
} else {
_argbBuffer[(y - top)*_lineWidth + i*_lineWidth + (x - left) +j] = color;
}
}
}
}
}
}
@ -41,23 +65,30 @@ protected:
}
public:
DrawCommand(int frameCount)
DrawCommand(int frameCount, bool useIntegerScaling = false)
{
_frameCount = frameCount > 0 ? frameCount : -1;
_frameCount = frameCount > 0 ? frameCount : 1;
_startFrame = PPU::GetFrameCount();
_useIntegerScaling = useIntegerScaling;
}
void Draw(uint32_t* argbBuffer, OverscanDimensions &overscan)
void Draw(uint32_t* argbBuffer, OverscanDimensions &overscan, uint32_t lineWidth, uint32_t frameNumber)
{
_argbBuffer = argbBuffer;
_overscan = overscan;
if(_startFrame <= frameNumber) {
_argbBuffer = argbBuffer;
_overscan = overscan;
_lineWidth = lineWidth;
_yScale = lineWidth / overscan.GetScreenWidth();
_xScale = (float)lineWidth / overscan.GetScreenWidth();
InternalDraw();
InternalDraw();
_frameCount--;
_frameCount--;
}
}
bool Expired()
{
return _frameCount == 0;
return _frameCount <= 0;
}
};

View file

@ -122,14 +122,15 @@ private:
protected:
void InternalDraw()
{
int x = _x;
int startX = (int)(_x * _xScale / _yScale);
int x = startX;
int y = _y;
for(char c : _text) {
if(c == '\n') {
x = _x;
x = startX;
y += 9;
} else if(c == '\t') {
x += (_tabSpace - (((x - _x) / 8) % _tabSpace)) * 8;
x += (_tabSpace - (((x - startX) / 8) % _tabSpace)) * 8;
} else {
int ch = GetCharNumber(c);
int width = GetCharWidth(c);
@ -151,7 +152,7 @@ protected:
public:
DrawStringCommand(int x, int y, string text, int color, int backColor, int frameCount) :
DrawCommand(frameCount), _x(x), _y(y), _color(color), _backColor(backColor), _text(text)
DrawCommand(frameCount, true), _x(x), _y(y), _color(color), _backColor(backColor), _text(text)
{
//Invert alpha byte - 0 = opaque, 255 = transparent (this way, no need to specifiy alpha channel all the time)
_color = (~color & 0xFF000000) | (color & 0xFFFFFF);

View file

@ -1112,8 +1112,8 @@ void PPU::Exec()
//Switch to alternate output buffer (VideoDecoder may still be decoding the last frame buffer)
_currentOutputBuffer = (_currentOutputBuffer == _outputBuffers[0]) ? _outputBuffers[1] : _outputBuffers[0];
} else if(_scanline == 240) {
_frameCount++;
SendFrame();
_frameCount++;
} else if(_scanline == _nmiScanline) {
BeginVBlank();
}

View file

@ -110,7 +110,7 @@ void VideoDecoder::DecodeFrame(bool synchronous)
if(_hdFilterEnabled) {
((HdVideoFilter*)_videoFilter.get())->SetHdScreenTiles(_hdScreenInfo);
}
_videoFilter->SendFrame(_ppuOutputBuffer, _isOddFrame);
_videoFilter->SendFrame(_ppuOutputBuffer, _frameNumber);
uint32_t* outputBuffer = (uint32_t*)_videoFilter->GetOutputBuffer();
FrameInfo frameInfo = _videoFilter->GetFrameInfo();
@ -168,7 +168,7 @@ uint32_t VideoDecoder::GetFrameCount()
void VideoDecoder::UpdateFrameSync(void *ppuOutputBuffer, HdScreenInfo *hdScreenInfo)
{
_isOddFrame = (PPU::GetFrameCount() & 0x01) == 0x01;
_frameNumber = PPU::GetFrameCount();
_hdScreenInfo = hdScreenInfo;
_ppuOutputBuffer = (uint16_t*)ppuOutputBuffer;
DecodeFrame(true);
@ -185,7 +185,7 @@ void VideoDecoder::UpdateFrame(void *ppuOutputBuffer, HdScreenInfo *hdScreenInfo
//At this point, we are sure that the decode thread is no longer busy
}
_isOddFrame = (PPU::GetFrameCount() & 0x01) == 0x01;
_frameNumber = PPU::GetFrameCount();
_hdScreenInfo = hdScreenInfo;
_ppuOutputBuffer = (uint16_t*)ppuOutputBuffer;
_frameChanged = true;

View file

@ -30,7 +30,7 @@ private:
uint16_t *_ppuOutputBuffer = nullptr;
HdScreenInfo *_hdScreenInfo = nullptr;
bool _hdFilterEnabled = false;
bool _isOddFrame = false;
uint32_t _frameNumber = 0;
unique_ptr<thread> _decodeThread;
unique_ptr<VideoHud> _hud;