Debugger: Lua - Fixed some bugs/limitations with drawing routines (now works with NTSC filters, etc.)
This commit is contained in:
parent
59858bdd58
commit
b641830058
10 changed files with 65 additions and 33 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "StandardController.h"
|
#include "StandardController.h"
|
||||||
#include "ScaleFilter.h"
|
#include "ScaleFilter.h"
|
||||||
#include "RotateFilter.h"
|
#include "RotateFilter.h"
|
||||||
|
#include "DebugHud.h"
|
||||||
|
|
||||||
BaseVideoFilter::BaseVideoFilter()
|
BaseVideoFilter::BaseVideoFilter()
|
||||||
{
|
{
|
||||||
|
@ -51,14 +52,17 @@ bool BaseVideoFilter::IsOddFrame()
|
||||||
return _isOddFrame;
|
return _isOddFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer, bool isOddFrame)
|
void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer, uint32_t frameNumber)
|
||||||
{
|
{
|
||||||
_frameLock.Acquire();
|
_frameLock.Acquire();
|
||||||
_overscan = EmulationSettings::GetOverscanDimensions();
|
_overscan = EmulationSettings::GetOverscanDimensions();
|
||||||
_isOddFrame = isOddFrame;
|
_isOddFrame = frameNumber % 2;
|
||||||
UpdateBufferSize();
|
UpdateBufferSize();
|
||||||
OnBeforeApplyFilter();
|
OnBeforeApplyFilter();
|
||||||
ApplyFilter(ppuOutputBuffer);
|
ApplyFilter(ppuOutputBuffer);
|
||||||
|
if(DebugHud::GetInstance()) {
|
||||||
|
DebugHud::GetInstance()->Draw((uint32_t*)_outputBuffer, _overscan, GetFrameInfo().Width, frameNumber);
|
||||||
|
}
|
||||||
_frameLock.Release();
|
_frameLock.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual ~BaseVideoFilter();
|
virtual ~BaseVideoFilter();
|
||||||
|
|
||||||
uint8_t* GetOutputBuffer();
|
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);
|
||||||
void TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream = nullptr);
|
void TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,11 @@ void DebugHud::ClearScreen()
|
||||||
_commands.clear();
|
_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();
|
auto lock = _commandLock.AcquireSafe();
|
||||||
for(shared_ptr<DrawCommand> &command : _commands) {
|
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());
|
_commands.erase(std::remove_if(_commands.begin(), _commands.end(), [](const shared_ptr<DrawCommand>& c) { return c->Expired(); }), _commands.end());
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public:
|
||||||
DebugHud();
|
DebugHud();
|
||||||
~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 ClearScreen();
|
||||||
|
|
||||||
void DrawPixel(int x, int y, int color, int frameCount);
|
void DrawPixel(int x, int y, int color, int frameCount);
|
||||||
|
|
|
@ -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)
|
void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "EmulationSettings.h"
|
#include "EmulationSettings.h"
|
||||||
|
#include "PPU.h"
|
||||||
|
|
||||||
class DrawCommand
|
class DrawCommand
|
||||||
{
|
{
|
||||||
|
@ -8,8 +9,14 @@ private:
|
||||||
int _frameCount;
|
int _frameCount;
|
||||||
uint32_t* _argbBuffer;
|
uint32_t* _argbBuffer;
|
||||||
OverscanDimensions _overscan;
|
OverscanDimensions _overscan;
|
||||||
|
uint32_t _lineWidth;
|
||||||
|
uint32_t _startFrame;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool _useIntegerScaling;
|
||||||
|
float _xScale;
|
||||||
|
int _yScale;
|
||||||
|
|
||||||
virtual void InternalDraw() = 0;
|
virtual void InternalDraw() = 0;
|
||||||
__forceinline void DrawPixel(uint32_t x, uint32_t y, int color)
|
__forceinline void DrawPixel(uint32_t x, uint32_t y, int color)
|
||||||
{
|
{
|
||||||
|
@ -20,13 +27,30 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t alpha = (color & 0xFF000000);
|
uint32_t alpha = (color & 0xFF000000);
|
||||||
|
if(alpha > 0) {
|
||||||
if(alpha == 0) {
|
if(_yScale == 1) {
|
||||||
//do nothing
|
if(alpha != 0xFF000000) {
|
||||||
} else if(alpha != 0xFF000000) {
|
BlendColors((uint8_t*)&_argbBuffer[(y - _overscan.Top)*_lineWidth + (x - _overscan.Left)], (uint8_t*)&color);
|
||||||
BlendColors((uint8_t*)&_argbBuffer[(y - _overscan.Top)*_overscan.GetScreenWidth() + (x - _overscan.Left)], (uint8_t*)&color);
|
|
||||||
} else {
|
} else {
|
||||||
_argbBuffer[(y - _overscan.Top)*_overscan.GetScreenWidth() + (x - _overscan.Left)] = color;
|
_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);
|
||||||
|
|
||||||
|
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:
|
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)
|
||||||
{
|
{
|
||||||
|
if(_startFrame <= frameNumber) {
|
||||||
_argbBuffer = argbBuffer;
|
_argbBuffer = argbBuffer;
|
||||||
_overscan = overscan;
|
_overscan = overscan;
|
||||||
|
_lineWidth = lineWidth;
|
||||||
|
_yScale = lineWidth / overscan.GetScreenWidth();
|
||||||
|
_xScale = (float)lineWidth / overscan.GetScreenWidth();
|
||||||
|
|
||||||
InternalDraw();
|
InternalDraw();
|
||||||
|
|
||||||
_frameCount--;
|
_frameCount--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Expired()
|
bool Expired()
|
||||||
{
|
{
|
||||||
return _frameCount == 0;
|
return _frameCount <= 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,14 +122,15 @@ private:
|
||||||
protected:
|
protected:
|
||||||
void InternalDraw()
|
void InternalDraw()
|
||||||
{
|
{
|
||||||
int x = _x;
|
int startX = (int)(_x * _xScale / _yScale);
|
||||||
|
int x = startX;
|
||||||
int y = _y;
|
int y = _y;
|
||||||
for(char c : _text) {
|
for(char c : _text) {
|
||||||
if(c == '\n') {
|
if(c == '\n') {
|
||||||
x = _x;
|
x = startX;
|
||||||
y += 9;
|
y += 9;
|
||||||
} else if(c == '\t') {
|
} else if(c == '\t') {
|
||||||
x += (_tabSpace - (((x - _x) / 8) % _tabSpace)) * 8;
|
x += (_tabSpace - (((x - startX) / 8) % _tabSpace)) * 8;
|
||||||
} else {
|
} else {
|
||||||
int ch = GetCharNumber(c);
|
int ch = GetCharNumber(c);
|
||||||
int width = GetCharWidth(c);
|
int width = GetCharWidth(c);
|
||||||
|
@ -151,7 +152,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DrawStringCommand(int x, int y, string text, int color, int backColor, int frameCount) :
|
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)
|
//Invert alpha byte - 0 = opaque, 255 = transparent (this way, no need to specifiy alpha channel all the time)
|
||||||
_color = (~color & 0xFF000000) | (color & 0xFFFFFF);
|
_color = (~color & 0xFF000000) | (color & 0xFFFFFF);
|
||||||
|
|
|
@ -1112,8 +1112,8 @@ void PPU::Exec()
|
||||||
//Switch to alternate output buffer (VideoDecoder may still be decoding the last frame buffer)
|
//Switch to alternate output buffer (VideoDecoder may still be decoding the last frame buffer)
|
||||||
_currentOutputBuffer = (_currentOutputBuffer == _outputBuffers[0]) ? _outputBuffers[1] : _outputBuffers[0];
|
_currentOutputBuffer = (_currentOutputBuffer == _outputBuffers[0]) ? _outputBuffers[1] : _outputBuffers[0];
|
||||||
} else if(_scanline == 240) {
|
} else if(_scanline == 240) {
|
||||||
_frameCount++;
|
|
||||||
SendFrame();
|
SendFrame();
|
||||||
|
_frameCount++;
|
||||||
} else if(_scanline == _nmiScanline) {
|
} else if(_scanline == _nmiScanline) {
|
||||||
BeginVBlank();
|
BeginVBlank();
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ void VideoDecoder::DecodeFrame(bool synchronous)
|
||||||
if(_hdFilterEnabled) {
|
if(_hdFilterEnabled) {
|
||||||
((HdVideoFilter*)_videoFilter.get())->SetHdScreenTiles(_hdScreenInfo);
|
((HdVideoFilter*)_videoFilter.get())->SetHdScreenTiles(_hdScreenInfo);
|
||||||
}
|
}
|
||||||
_videoFilter->SendFrame(_ppuOutputBuffer, _isOddFrame);
|
_videoFilter->SendFrame(_ppuOutputBuffer, _frameNumber);
|
||||||
|
|
||||||
uint32_t* outputBuffer = (uint32_t*)_videoFilter->GetOutputBuffer();
|
uint32_t* outputBuffer = (uint32_t*)_videoFilter->GetOutputBuffer();
|
||||||
FrameInfo frameInfo = _videoFilter->GetFrameInfo();
|
FrameInfo frameInfo = _videoFilter->GetFrameInfo();
|
||||||
|
@ -168,7 +168,7 @@ uint32_t VideoDecoder::GetFrameCount()
|
||||||
|
|
||||||
void VideoDecoder::UpdateFrameSync(void *ppuOutputBuffer, HdScreenInfo *hdScreenInfo)
|
void VideoDecoder::UpdateFrameSync(void *ppuOutputBuffer, HdScreenInfo *hdScreenInfo)
|
||||||
{
|
{
|
||||||
_isOddFrame = (PPU::GetFrameCount() & 0x01) == 0x01;
|
_frameNumber = PPU::GetFrameCount();
|
||||||
_hdScreenInfo = hdScreenInfo;
|
_hdScreenInfo = hdScreenInfo;
|
||||||
_ppuOutputBuffer = (uint16_t*)ppuOutputBuffer;
|
_ppuOutputBuffer = (uint16_t*)ppuOutputBuffer;
|
||||||
DecodeFrame(true);
|
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
|
//At this point, we are sure that the decode thread is no longer busy
|
||||||
}
|
}
|
||||||
|
|
||||||
_isOddFrame = (PPU::GetFrameCount() & 0x01) == 0x01;
|
_frameNumber = PPU::GetFrameCount();
|
||||||
_hdScreenInfo = hdScreenInfo;
|
_hdScreenInfo = hdScreenInfo;
|
||||||
_ppuOutputBuffer = (uint16_t*)ppuOutputBuffer;
|
_ppuOutputBuffer = (uint16_t*)ppuOutputBuffer;
|
||||||
_frameChanged = true;
|
_frameChanged = true;
|
||||||
|
|
|
@ -30,7 +30,7 @@ private:
|
||||||
uint16_t *_ppuOutputBuffer = nullptr;
|
uint16_t *_ppuOutputBuffer = nullptr;
|
||||||
HdScreenInfo *_hdScreenInfo = nullptr;
|
HdScreenInfo *_hdScreenInfo = nullptr;
|
||||||
bool _hdFilterEnabled = false;
|
bool _hdFilterEnabled = false;
|
||||||
bool _isOddFrame = false;
|
uint32_t _frameNumber = 0;
|
||||||
|
|
||||||
unique_ptr<thread> _decodeThread;
|
unique_ptr<thread> _decodeThread;
|
||||||
unique_ptr<VideoHud> _hud;
|
unique_ptr<VideoHud> _hud;
|
||||||
|
|
Loading…
Add table
Reference in a new issue