HD Packs: Allow non-ntsc video filters to be used on top of a HD pack

This commit is contained in:
Souryo 2017-08-15 23:59:55 -04:00
parent 6ca49dd4af
commit 6691660617
8 changed files with 118 additions and 84 deletions

View file

@ -12,7 +12,6 @@ ScaleFilter::ScaleFilter(ScaleFilterType scaleFilterType, uint32_t scale)
{ {
_scaleFilterType = scaleFilterType; _scaleFilterType = scaleFilterType;
_filterScale = scale; _filterScale = scale;
_decodedPpuBuffer = new uint32_t[PPU::PixelCount];
if(!_hqxInitDone && _scaleFilterType == ScaleFilterType::HQX) { if(!_hqxInitDone && _scaleFilterType == ScaleFilterType::HQX) {
hqxInit(); hqxInit();
@ -22,68 +21,72 @@ ScaleFilter::ScaleFilter(ScaleFilterType scaleFilterType, uint32_t scale)
ScaleFilter::~ScaleFilter() ScaleFilter::~ScaleFilter()
{ {
delete[] _decodedPpuBuffer; if(_outputBuffer) {
delete[] _outputBuffer;
}
} }
FrameInfo ScaleFilter::GetFrameInfo() uint32_t ScaleFilter::GetScale()
{ {
OverscanDimensions overscan = GetOverscan(); return _filterScale;
return{ overscan.GetScreenWidth()*_filterScale, overscan.GetScreenHeight()*_filterScale, PPU::ScreenWidth*_filterScale, PPU::ScreenHeight*_filterScale, 4 };
} }
void ScaleFilter::ApplyPrescaleFilter() void ScaleFilter::ApplyPrescaleFilter(uint32_t *inputArgbBuffer)
{ {
uint32_t* outputBuffer = (uint32_t*)GetOutputBuffer(); uint32_t* outputBuffer = _outputBuffer;
OverscanDimensions overscan = GetOverscan(); for(uint32_t y = 0; y < _height; y++) {
uint32_t height = overscan.GetScreenHeight(); for(uint32_t x = 0; x < _width; x++) {
uint32_t width = overscan.GetScreenWidth();
uint32_t *inputBuffer = _decodedPpuBuffer;
for(uint32_t y = 0; y < height; y++) {
for(uint32_t x = 0; x < width; x++) {
for(uint32_t i = 0; i < _filterScale; i++) { for(uint32_t i = 0; i < _filterScale; i++) {
*(outputBuffer++) = *inputBuffer; *(outputBuffer++) = *inputArgbBuffer;
} }
inputBuffer++; inputArgbBuffer++;
} }
for(uint32_t i = 1; i< _filterScale; i++) { for(uint32_t i = 1; i < _filterScale; i++) {
memcpy(outputBuffer, outputBuffer - width*_filterScale, width*_filterScale *4); memcpy(outputBuffer, outputBuffer - _width*_filterScale, _width*_filterScale *4);
outputBuffer += width*_filterScale; outputBuffer += _width*_filterScale;
} }
} }
} }
void ScaleFilter::ApplyFilter(uint16_t *ppuOutputBuffer) void ScaleFilter::UpdateOutputBuffer(uint32_t width, uint32_t height)
{ {
DecodePpuBuffer(ppuOutputBuffer, _decodedPpuBuffer, false); if(!_outputBuffer || width != _width || height != _height) {
if(_outputBuffer) {
delete[] _outputBuffer;
}
OverscanDimensions overscan = GetOverscan(); _width = width;
uint32_t height = overscan.GetScreenHeight(); _height = height;
uint32_t width = overscan.GetScreenWidth(); _outputBuffer = new uint32_t[_width*_height*_filterScale*_filterScale];
uint32_t* outputBuffer = (uint32_t*)GetOutputBuffer(); }
}
uint32_t* ScaleFilter::ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, uint32_t height)
{
UpdateOutputBuffer(width, height);
if(_scaleFilterType == ScaleFilterType::xBRZ) { if(_scaleFilterType == ScaleFilterType::xBRZ) {
xbrz::scale(_filterScale, _decodedPpuBuffer, outputBuffer, width, height, xbrz::ColorFormat::ARGB); xbrz::scale(_filterScale, inputArgbBuffer, _outputBuffer, width, height, xbrz::ColorFormat::ARGB);
} else if(_scaleFilterType == ScaleFilterType::HQX) { } else if(_scaleFilterType == ScaleFilterType::HQX) {
hqx(_filterScale, _decodedPpuBuffer, outputBuffer, width, height); hqx(_filterScale, inputArgbBuffer, _outputBuffer, width, height);
} else if(_scaleFilterType == ScaleFilterType::Scale2x) { } else if(_scaleFilterType == ScaleFilterType::Scale2x) {
scale(_filterScale, outputBuffer, width*sizeof(uint32_t)*_filterScale, _decodedPpuBuffer, width*sizeof(uint32_t), 4, width, height); scale(_filterScale, _outputBuffer, width*sizeof(uint32_t)*_filterScale, inputArgbBuffer, width*sizeof(uint32_t), 4, width, height);
} else if(_scaleFilterType == ScaleFilterType::_2xSai) { } else if(_scaleFilterType == ScaleFilterType::_2xSai) {
twoxsai_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale); twoxsai_generic_xrgb8888(width, height, inputArgbBuffer, width, _outputBuffer, width * _filterScale);
} else if(_scaleFilterType == ScaleFilterType::Super2xSai) { } else if(_scaleFilterType == ScaleFilterType::Super2xSai) {
supertwoxsai_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale); supertwoxsai_generic_xrgb8888(width, height, inputArgbBuffer, width, _outputBuffer, width * _filterScale);
} else if(_scaleFilterType == ScaleFilterType::SuperEagle) { } else if(_scaleFilterType == ScaleFilterType::SuperEagle) {
supereagle_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale); supereagle_generic_xrgb8888(width, height, inputArgbBuffer, width, _outputBuffer, width * _filterScale);
} else if(_scaleFilterType == ScaleFilterType::Prescale) { } else if(_scaleFilterType == ScaleFilterType::Prescale) {
ApplyPrescaleFilter(); ApplyPrescaleFilter(inputArgbBuffer);
} }
double scanlineIntensity = 1.0 - EmulationSettings::GetPictureSettings().ScanlineIntensity; double scanlineIntensity = 1.0 - EmulationSettings::GetPictureSettings().ScanlineIntensity;
if(scanlineIntensity < 1.0) { if(scanlineIntensity < 1.0) {
for(int y = 1, yMax = height * _filterScale; y < yMax; y += 2) { for(int y = 1, yMax = height * _filterScale; y < yMax; y += 2) {
for(int x = 0, xMax = width * _filterScale; x < xMax; x++) { for(int x = 0, xMax = width * _filterScale; x < xMax; x++) {
uint32_t &color = outputBuffer[y*xMax + x]; uint32_t &color = _outputBuffer[y*xMax + x];
uint8_t r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF; uint8_t r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF;
r = (uint8_t)(r * scanlineIntensity); r = (uint8_t)(r * scanlineIntensity);
g = (uint8_t)(g * scanlineIntensity); g = (uint8_t)(g * scanlineIntensity);
@ -92,4 +95,6 @@ void ScaleFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
} }
} }
} }
return _outputBuffer;
} }

View file

@ -3,20 +3,23 @@
#include "stdafx.h" #include "stdafx.h"
#include "DefaultVideoFilter.h" #include "DefaultVideoFilter.h"
class ScaleFilter : public DefaultVideoFilter class ScaleFilter
{ {
private: private:
static bool _hqxInitDone; static bool _hqxInitDone;
uint32_t *_decodedPpuBuffer;
uint32_t _filterScale; uint32_t _filterScale;
ScaleFilterType _scaleFilterType; ScaleFilterType _scaleFilterType;
uint32_t *_outputBuffer = nullptr;
uint32_t _width = 0;
uint32_t _height = 0;
void ApplyPrescaleFilter(); void ApplyPrescaleFilter(uint32_t *inputArgbBuffer);
void UpdateOutputBuffer(uint32_t width, uint32_t height);
public: public:
ScaleFilter(ScaleFilterType scaleFilterType, uint32_t scale); ScaleFilter(ScaleFilterType scaleFilterType, uint32_t scale);
virtual ~ScaleFilter(); ~ScaleFilter();
void ApplyFilter(uint16_t *ppuOutputBuffer); uint32_t GetScale();
FrameInfo GetFrameInfo(); uint32_t* ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, uint32_t height);
}; };

View file

@ -65,42 +65,44 @@ void VideoDecoder::GetScreenSize(ScreenSize &size, bool ignoreScale)
void VideoDecoder::UpdateVideoFilter() void VideoDecoder::UpdateVideoFilter()
{ {
VideoFilterType newFilter = EmulationSettings::GetVideoFilterType(); VideoFilterType newFilter = EmulationSettings::GetVideoFilterType();
if(_hdScreenTiles) {
newFilter = VideoFilterType::HdPack;
}
if(_videoFilterType != newFilter || _videoFilter == nullptr) { if(_videoFilterType != newFilter || _videoFilter == nullptr || (_hdScreenTiles && !_hdFilterEnabled) || (!_hdScreenTiles && _hdFilterEnabled)) {
_videoFilterType = newFilter; _videoFilterType = newFilter;
_videoFilter.reset(new DefaultVideoFilter());
_scaleFilter.reset();
switch(_videoFilterType) { switch(_videoFilterType) {
case VideoFilterType::None: _videoFilter.reset(new DefaultVideoFilter()); 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: _videoFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 2)); break; case VideoFilterType::xBRZ2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 2)); break;
case VideoFilterType::xBRZ3x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 3)); break; case VideoFilterType::xBRZ3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 3)); break;
case VideoFilterType::xBRZ4x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 4)); break; case VideoFilterType::xBRZ4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 4)); break;
case VideoFilterType::xBRZ5x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 5)); break; case VideoFilterType::xBRZ5x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 5)); break;
case VideoFilterType::xBRZ6x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 6)); break; case VideoFilterType::xBRZ6x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::xBRZ, 6)); break;
case VideoFilterType::HQ2x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 2)); break; case VideoFilterType::HQ2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 2)); break;
case VideoFilterType::HQ3x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 3)); break; case VideoFilterType::HQ3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 3)); break;
case VideoFilterType::HQ4x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 4)); break; case VideoFilterType::HQ4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::HQX, 4)); break;
case VideoFilterType::Scale2x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 2)); break; case VideoFilterType::Scale2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 2)); break;
case VideoFilterType::Scale3x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 3)); break; case VideoFilterType::Scale3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 3)); break;
case VideoFilterType::Scale4x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 4)); break; case VideoFilterType::Scale4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Scale2x, 4)); break;
case VideoFilterType::_2xSai: _videoFilter.reset(new ScaleFilter(ScaleFilterType::_2xSai, 2)); break; case VideoFilterType::_2xSai: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::_2xSai, 2)); break;
case VideoFilterType::Super2xSai: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Super2xSai, 2)); break; case VideoFilterType::Super2xSai: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Super2xSai, 2)); break;
case VideoFilterType::SuperEagle: _videoFilter.reset(new ScaleFilter(ScaleFilterType::SuperEagle, 2)); break; case VideoFilterType::SuperEagle: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::SuperEagle, 2)); break;
case VideoFilterType::Prescale2x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 2)); break; case VideoFilterType::Prescale2x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 2)); break;
case VideoFilterType::Prescale3x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 3)); break; case VideoFilterType::Prescale3x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 3)); break;
case VideoFilterType::Prescale4x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 4)); break; case VideoFilterType::Prescale4x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 4)); break;
case VideoFilterType::Prescale6x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 6)); break; case VideoFilterType::Prescale6x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 6)); break;
case VideoFilterType::Prescale8x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 8)); break; case VideoFilterType::Prescale8x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 8)); break;
case VideoFilterType::Prescale10x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 10)); break; case VideoFilterType::Prescale10x: _scaleFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 10)); break;
}
case VideoFilterType::HdPack: _videoFilter.reset(new HdVideoFilter()); break; _hdFilterEnabled = false;
if(_hdScreenTiles) {
_videoFilter.reset(new HdVideoFilter());
_hdFilterEnabled = true;
} }
} }
} }
@ -109,11 +111,16 @@ void VideoDecoder::DecodeFrame()
{ {
UpdateVideoFilter(); UpdateVideoFilter();
if(_videoFilterType == VideoFilterType::HdPack) { if(_hdFilterEnabled) {
((HdVideoFilter*)_videoFilter.get())->SetHdScreenTiles(_hdScreenTiles); ((HdVideoFilter*)_videoFilter.get())->SetHdScreenTiles(_hdScreenTiles);
} }
_videoFilter->SendFrame(_ppuOutputBuffer); _videoFilter->SendFrame(_ppuOutputBuffer);
uint32_t* outputBuffer = (uint32_t*)_videoFilter->GetOutputBuffer();
if(_scaleFilter) {
outputBuffer = _scaleFilter->ApplyFilter(outputBuffer, _videoFilter->GetFrameInfo().Width, _videoFilter->GetFrameInfo().Height);
}
ScreenSize screenSize; ScreenSize screenSize;
GetScreenSize(screenSize, true); GetScreenSize(screenSize, true);
if(_previousScale != EmulationSettings::GetVideoScale() || screenSize.Height != _previousScreenSize.Height || screenSize.Width != _previousScreenSize.Width) { if(_previousScale != EmulationSettings::GetVideoScale() || screenSize.Height != _previousScreenSize.Height || screenSize.Width != _previousScreenSize.Width) {
@ -123,11 +130,17 @@ void VideoDecoder::DecodeFrame()
_previousScreenSize = screenSize; _previousScreenSize = screenSize;
FrameInfo frameInfo = _videoFilter->GetFrameInfo(); FrameInfo frameInfo = _videoFilter->GetFrameInfo();
if(_scaleFilter) {
frameInfo.Height *= _scaleFilter->GetScale();
frameInfo.Width *= _scaleFilter->GetScale();
frameInfo.OriginalHeight *= _scaleFilter->GetScale();
frameInfo.OriginalWidth *= _scaleFilter->GetScale();
}
_frameChanged = false; _frameChanged = false;
//Rewind manager will take care of sending the correct frame to the video renderer //Rewind manager will take care of sending the correct frame to the video renderer
RewindManager::SendFrame(_videoFilter->GetOutputBuffer(), frameInfo.Width, frameInfo.Height); RewindManager::SendFrame(outputBuffer, frameInfo.Width, frameInfo.Height);
} }
void VideoDecoder::DebugDecodeFrame(uint16_t* inputBuffer, uint32_t* outputBuffer, uint32_t length) void VideoDecoder::DebugDecodeFrame(uint16_t* inputBuffer, uint32_t* outputBuffer, uint32_t length)

View file

@ -9,6 +9,7 @@ using std::thread;
#include "FrameInfo.h" #include "FrameInfo.h"
class BaseVideoFilter; class BaseVideoFilter;
class ScaleFilter;
class IRenderingDevice; class IRenderingDevice;
struct HdPpuPixelInfo; struct HdPpuPixelInfo;
@ -26,6 +27,7 @@ private:
uint16_t *_ppuOutputBuffer = nullptr; uint16_t *_ppuOutputBuffer = nullptr;
HdPpuPixelInfo *_hdScreenTiles = nullptr; HdPpuPixelInfo *_hdScreenTiles = nullptr;
bool _hdFilterEnabled = false;
unique_ptr<thread> _decodeThread; unique_ptr<thread> _decodeThread;
@ -40,6 +42,7 @@ private:
VideoFilterType _videoFilterType = VideoFilterType::None; VideoFilterType _videoFilterType = VideoFilterType::None;
unique_ptr<BaseVideoFilter> _videoFilter; unique_ptr<BaseVideoFilter> _videoFilter;
unique_ptr<ScaleFilter> _scaleFilter;
void UpdateVideoFilter(); void UpdateVideoFilter();

View file

@ -185,6 +185,8 @@ namespace Mesen.GUI.Forms
this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem(); this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem(); this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem(); this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem25 = new System.Windows.Forms.ToolStripSeparator();
this.mnuEditHeader = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHelp = new System.Windows.Forms.ToolStripMenuItem(); this.mnuHelp = new System.Windows.Forms.ToolStripMenuItem();
this.mnuCheckForUpdates = new System.Windows.Forms.ToolStripMenuItem(); this.mnuCheckForUpdates = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem20 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem20 = new System.Windows.Forms.ToolStripSeparator();
@ -192,8 +194,6 @@ namespace Mesen.GUI.Forms
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuHelpWindow = new System.Windows.Forms.ToolStripMenuItem(); this.mnuHelpWindow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem(); this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem25 = new System.Windows.Forms.ToolStripSeparator();
this.mnuEditHeader = new System.Windows.Forms.ToolStripMenuItem();
this.panelRenderer.SuspendLayout(); this.panelRenderer.SuspendLayout();
this.panelInfo.SuspendLayout(); this.panelInfo.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picIcon)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.picIcon)).BeginInit();
@ -307,7 +307,7 @@ namespace Mesen.GUI.Forms
this.mnuGame, this.mnuGame,
this.mnuOptions, this.mnuOptions,
this.mnuTools, this.mnuTools,
this.mnuDebug, this.mnuDebug,
this.mnuHelp}); this.mnuHelp});
this.menuStrip.Location = new System.Drawing.Point(0, 0); this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip"; this.menuStrip.Name = "menuStrip";
@ -882,7 +882,7 @@ namespace Mesen.GUI.Forms
// //
this.mnuScale4xFilter.Name = "mnuScale4xFilter"; this.mnuScale4xFilter.Name = "mnuScale4xFilter";
this.mnuScale4xFilter.Size = new System.Drawing.Size(206, 22); this.mnuScale4xFilter.Size = new System.Drawing.Size(206, 22);
this.mnuScale4xFilter.Text = "Scale 4x"; this.mnuScale4xFilter.Text = "Scale4x";
this.mnuScale4xFilter.Click += new System.EventHandler(this.mnuScale4xFilter_Click); this.mnuScale4xFilter.Click += new System.EventHandler(this.mnuScale4xFilter_Click);
// //
// toolStripMenuItem23 // toolStripMenuItem23
@ -1500,6 +1500,19 @@ namespace Mesen.GUI.Forms
this.mnuTraceLogger.Text = "Trace Logger"; this.mnuTraceLogger.Text = "Trace Logger";
this.mnuTraceLogger.Click += new System.EventHandler(this.mnuTraceLogger_Click); this.mnuTraceLogger.Click += new System.EventHandler(this.mnuTraceLogger_Click);
// //
// toolStripMenuItem25
//
this.toolStripMenuItem25.Name = "toolStripMenuItem25";
this.toolStripMenuItem25.Size = new System.Drawing.Size(193, 6);
//
// mnuEditHeader
//
this.mnuEditHeader.Image = global::Mesen.GUI.Properties.Resources.Edit;
this.mnuEditHeader.Name = "mnuEditHeader";
this.mnuEditHeader.Size = new System.Drawing.Size(196, 22);
this.mnuEditHeader.Text = "Edit iNES Header";
this.mnuEditHeader.Click += new System.EventHandler(this.mnuEditHeader_Click);
//
// mnuHelp // mnuHelp
// //
this.mnuHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.mnuHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -1554,19 +1567,6 @@ namespace Mesen.GUI.Forms
this.mnuAbout.Text = "About"; this.mnuAbout.Text = "About";
this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click); this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
// //
// toolStripMenuItem25
//
this.toolStripMenuItem25.Name = "toolStripMenuItem25";
this.toolStripMenuItem25.Size = new System.Drawing.Size(193, 6);
//
// mnuEditHeader
//
this.mnuEditHeader.Image = global::Mesen.GUI.Properties.Resources.Edit;
this.mnuEditHeader.Name = "mnuEditHeader";
this.mnuEditHeader.Size = new System.Drawing.Size(196, 22);
this.mnuEditHeader.Text = "Edit iNES Header";
this.mnuEditHeader.Click += new System.EventHandler(this.mnuEditHeader_Click);
//
// frmMain // frmMain
// //
this.AllowDrop = true; this.AllowDrop = true;

View file

@ -611,6 +611,12 @@ namespace Mesen.GUI.Forms
mnuSelectDisk.Enabled = autoInsertDisabled; mnuSelectDisk.Enabled = autoInsertDisabled;
mnuEjectDisk.Enabled = autoInsertDisabled; mnuEjectDisk.Enabled = autoInsertDisabled;
mnuSwitchDiskSide.Enabled = autoInsertDisabled; mnuSwitchDiskSide.Enabled = autoInsertDisabled;
bool isHdPackLoader = InteropEmu.IsHdPackLoaded();
mnuNtscFilter.Enabled = !isHdPackLoader;
mnuNtscBisqwitQuarterFilter.Enabled = !isHdPackLoader;
mnuNtscBisqwitHalfFilter.Enabled = !isHdPackLoader;
mnuNtscBisqwitFullFilter.Enabled = !isHdPackLoader;
} }
} catch { } } catch { }
} }

View file

@ -533,6 +533,8 @@ namespace Mesen.GUI
yScroll = (int)(ppuScroll >> 16) & 0xFFFF; yScroll = (int)(ppuScroll >> 16) & 0xFFFF;
} }
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsHdPackLoaded();
[DllImport(DLLPath)] public static extern void HdBuilderStartRecording( [DllImport(DLLPath)] public static extern void HdBuilderStartRecording(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string saveFolder, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string saveFolder,
ScaleFilterType filterType, ScaleFilterType filterType,

View file

@ -475,6 +475,8 @@ namespace InteropEmu {
} }
} }
DllExport bool __stdcall IsHdPackLoaded() { return Console::GetHdData() != nullptr; }
DllExport void __stdcall HdBuilderStartRecording(char* saveFolder, ScaleFilterType filterType, uint32_t scale, uint32_t flags, uint32_t chrRamBankSize) { Console::StartRecordingHdPack(saveFolder, filterType, scale, flags, chrRamBankSize); } DllExport void __stdcall HdBuilderStartRecording(char* saveFolder, ScaleFilterType filterType, uint32_t scale, uint32_t flags, uint32_t chrRamBankSize) { Console::StartRecordingHdPack(saveFolder, filterType, scale, flags, chrRamBankSize); }
DllExport void __stdcall HdBuilderStopRecording() { Console::StopRecordingHdPack(); } DllExport void __stdcall HdBuilderStopRecording() { Console::StopRecordingHdPack(); }