UI: Added video options (scale, filters, aspect ratio)
This commit is contained in:
parent
337416f3a5
commit
60af2e2f64
45 changed files with 2597 additions and 913 deletions
|
@ -76,6 +76,15 @@ uint32_t* BaseVideoFilter::GetOutputBuffer()
|
||||||
return _outputBuffer;
|
return _outputBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t BaseVideoFilter::ApplyScanlineEffect(uint32_t argb, uint8_t scanlineIntensity)
|
||||||
|
{
|
||||||
|
uint8_t r = ((argb & 0xFF0000) >> 16) * scanlineIntensity / 255;
|
||||||
|
uint8_t g = ((argb & 0xFF00) >> 8) * scanlineIntensity / 255;
|
||||||
|
uint8_t b = (argb & 0xFF) * scanlineIntensity / 255;
|
||||||
|
|
||||||
|
return 0xFF000000 | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseVideoFilter::TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream)
|
void BaseVideoFilter::TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream)
|
||||||
{
|
{
|
||||||
uint32_t* pngBuffer;
|
uint32_t* pngBuffer;
|
||||||
|
|
|
@ -23,6 +23,7 @@ protected:
|
||||||
virtual void ApplyFilter(uint16_t *ppuOutputBuffer) = 0;
|
virtual void ApplyFilter(uint16_t *ppuOutputBuffer) = 0;
|
||||||
virtual void OnBeforeApplyFilter();
|
virtual void OnBeforeApplyFilter();
|
||||||
bool IsOddFrame();
|
bool IsOddFrame();
|
||||||
|
uint32_t ApplyScanlineEffect(uint32_t argb, uint8_t scanlineIntensity);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BaseVideoFilter(shared_ptr<Console> console);
|
BaseVideoFilter(shared_ptr<Console> console);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "MessageManager.h"
|
#include "MessageManager.h"
|
||||||
#include "KeyManager.h"
|
#include "KeyManager.h"
|
||||||
#include "EventType.h"
|
#include "EventType.h"
|
||||||
|
#include "EmuSettings.h"
|
||||||
#include "../Utilities/Timer.h"
|
#include "../Utilities/Timer.h"
|
||||||
#include "../Utilities/VirtualFile.h"
|
#include "../Utilities/VirtualFile.h"
|
||||||
#include "../Utilities/PlatformUtilities.h"
|
#include "../Utilities/PlatformUtilities.h"
|
||||||
|
@ -31,6 +32,7 @@ Console::~Console()
|
||||||
|
|
||||||
void Console::Initialize()
|
void Console::Initialize()
|
||||||
{
|
{
|
||||||
|
_settings.reset(new EmuSettings());
|
||||||
_notificationManager.reset(new NotificationManager());
|
_notificationManager.reset(new NotificationManager());
|
||||||
_videoDecoder.reset(new VideoDecoder(shared_from_this()));
|
_videoDecoder.reset(new VideoDecoder(shared_from_this()));
|
||||||
_videoRenderer.reset(new VideoRenderer(shared_from_this()));
|
_videoRenderer.reset(new VideoRenderer(shared_from_this()));
|
||||||
|
@ -176,6 +178,11 @@ shared_ptr<NotificationManager> Console::GetNotificationManager()
|
||||||
return _notificationManager;
|
return _notificationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<EmuSettings> Console::GetSettings()
|
||||||
|
{
|
||||||
|
return _settings;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<DebugHud> Console::GetDebugHud()
|
shared_ptr<DebugHud> Console::GetDebugHud()
|
||||||
{
|
{
|
||||||
return _debugHud;
|
return _debugHud;
|
||||||
|
|
|
@ -17,6 +17,7 @@ class SoundMixer;
|
||||||
class VideoRenderer;
|
class VideoRenderer;
|
||||||
class VideoDecoder;
|
class VideoDecoder;
|
||||||
class NotificationManager;
|
class NotificationManager;
|
||||||
|
class EmuSettings;
|
||||||
enum class MemoryOperationType;
|
enum class MemoryOperationType;
|
||||||
enum class SnesMemoryType;
|
enum class SnesMemoryType;
|
||||||
enum class EventType;
|
enum class EventType;
|
||||||
|
@ -40,6 +41,7 @@ private:
|
||||||
shared_ptr<VideoRenderer> _videoRenderer;
|
shared_ptr<VideoRenderer> _videoRenderer;
|
||||||
shared_ptr<VideoDecoder> _videoDecoder;
|
shared_ptr<VideoDecoder> _videoDecoder;
|
||||||
shared_ptr<DebugHud> _debugHud;
|
shared_ptr<DebugHud> _debugHud;
|
||||||
|
shared_ptr<EmuSettings> _settings;
|
||||||
|
|
||||||
thread::id _emulationThreadId;
|
thread::id _emulationThreadId;
|
||||||
|
|
||||||
|
@ -62,6 +64,7 @@ public:
|
||||||
shared_ptr<VideoRenderer> GetVideoRenderer();
|
shared_ptr<VideoRenderer> GetVideoRenderer();
|
||||||
shared_ptr<VideoDecoder> GetVideoDecoder();
|
shared_ptr<VideoDecoder> GetVideoDecoder();
|
||||||
shared_ptr<NotificationManager> GetNotificationManager();
|
shared_ptr<NotificationManager> GetNotificationManager();
|
||||||
|
shared_ptr<EmuSettings> GetSettings();
|
||||||
|
|
||||||
shared_ptr<DebugHud> GetDebugHud();
|
shared_ptr<DebugHud> GetDebugHud();
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,11 @@
|
||||||
<ClInclude Include="Cpu.h" />
|
<ClInclude Include="Cpu.h" />
|
||||||
<ClInclude Include="DebugBreakHelper.h" />
|
<ClInclude Include="DebugBreakHelper.h" />
|
||||||
<ClInclude Include="DummyCpu.h" />
|
<ClInclude Include="DummyCpu.h" />
|
||||||
|
<ClInclude Include="EmuSettings.h" />
|
||||||
<ClInclude Include="EventManager.h" />
|
<ClInclude Include="EventManager.h" />
|
||||||
<ClInclude Include="EventType.h" />
|
<ClInclude Include="EventType.h" />
|
||||||
<ClInclude Include="ExpressionEvaluator.h" />
|
<ClInclude Include="ExpressionEvaluator.h" />
|
||||||
|
<ClInclude Include="NtscFilter.h" />
|
||||||
<ClInclude Include="PpuTools.h" />
|
<ClInclude Include="PpuTools.h" />
|
||||||
<ClInclude Include="RegisterHandlerB.h" />
|
<ClInclude Include="RegisterHandlerB.h" />
|
||||||
<ClInclude Include="CpuTypes.h" />
|
<ClInclude Include="CpuTypes.h" />
|
||||||
|
@ -101,6 +103,7 @@
|
||||||
<ClInclude Include="RamHandler.h" />
|
<ClInclude Include="RamHandler.h" />
|
||||||
<ClInclude Include="RegisterHandlerA.h" />
|
<ClInclude Include="RegisterHandlerA.h" />
|
||||||
<ClInclude Include="RomHandler.h" />
|
<ClInclude Include="RomHandler.h" />
|
||||||
|
<ClInclude Include="ScaleFilter.h" />
|
||||||
<ClInclude Include="SettingTypes.h" />
|
<ClInclude Include="SettingTypes.h" />
|
||||||
<ClInclude Include="SnesController.h" />
|
<ClInclude Include="SnesController.h" />
|
||||||
<ClInclude Include="SNES_SPC.h" />
|
<ClInclude Include="SNES_SPC.h" />
|
||||||
|
@ -133,6 +136,7 @@
|
||||||
<ClCompile Include="Disassembler.cpp" />
|
<ClCompile Include="Disassembler.cpp" />
|
||||||
<ClCompile Include="DisassemblyInfo.cpp" />
|
<ClCompile Include="DisassemblyInfo.cpp" />
|
||||||
<ClCompile Include="DmaController.cpp" />
|
<ClCompile Include="DmaController.cpp" />
|
||||||
|
<ClCompile Include="EmuSettings.cpp" />
|
||||||
<ClCompile Include="EventManager.cpp" />
|
<ClCompile Include="EventManager.cpp" />
|
||||||
<ClCompile Include="ExpressionEvaluator.cpp" />
|
<ClCompile Include="ExpressionEvaluator.cpp" />
|
||||||
<ClCompile Include="InternalRegisters.cpp" />
|
<ClCompile Include="InternalRegisters.cpp" />
|
||||||
|
@ -141,8 +145,10 @@
|
||||||
<ClCompile Include="MemoryManager.cpp" />
|
<ClCompile Include="MemoryManager.cpp" />
|
||||||
<ClCompile Include="MessageManager.cpp" />
|
<ClCompile Include="MessageManager.cpp" />
|
||||||
<ClCompile Include="NotificationManager.cpp" />
|
<ClCompile Include="NotificationManager.cpp" />
|
||||||
|
<ClCompile Include="NtscFilter.cpp" />
|
||||||
<ClCompile Include="Ppu.cpp" />
|
<ClCompile Include="Ppu.cpp" />
|
||||||
<ClCompile Include="PpuTools.cpp" />
|
<ClCompile Include="PpuTools.cpp" />
|
||||||
|
<ClCompile Include="ScaleFilter.cpp" />
|
||||||
<ClCompile Include="SNES_SPC.cpp" />
|
<ClCompile Include="SNES_SPC.cpp" />
|
||||||
<ClCompile Include="SNES_SPC_misc.cpp" />
|
<ClCompile Include="SNES_SPC_misc.cpp" />
|
||||||
<ClCompile Include="SNES_SPC_state.cpp" />
|
<ClCompile Include="SNES_SPC_state.cpp" />
|
||||||
|
|
|
@ -209,6 +209,15 @@
|
||||||
<ClInclude Include="DebugBreakHelper.h">
|
<ClInclude Include="DebugBreakHelper.h">
|
||||||
<Filter>Debugger</Filter>
|
<Filter>Debugger</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="EmuSettings.h">
|
||||||
|
<Filter>Misc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ScaleFilter.h">
|
||||||
|
<Filter>Video</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="NtscFilter.h">
|
||||||
|
<Filter>Video</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp" />
|
<ClCompile Include="stdafx.cpp" />
|
||||||
|
@ -326,6 +335,15 @@
|
||||||
<ClCompile Include="PpuTools.cpp">
|
<ClCompile Include="PpuTools.cpp">
|
||||||
<Filter>Debugger</Filter>
|
<Filter>Debugger</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="EmuSettings.cpp">
|
||||||
|
<Filter>Misc</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ScaleFilter.cpp">
|
||||||
|
<Filter>Video</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="NtscFilter.cpp">
|
||||||
|
<Filter>Video</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="SNES">
|
<Filter Include="SNES">
|
||||||
|
|
|
@ -5,17 +5,16 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "DebugHud.h"
|
#include "DebugHud.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
#include "EmuSettings.h"
|
||||||
|
#include "SettingTypes.h"
|
||||||
|
|
||||||
DefaultVideoFilter::DefaultVideoFilter(shared_ptr<Console> console) : BaseVideoFilter(console)
|
DefaultVideoFilter::DefaultVideoFilter(shared_ptr<Console> console) : BaseVideoFilter(console)
|
||||||
{
|
{
|
||||||
InitConversionMatrix(_pictureSettings.Hue, _pictureSettings.Saturation);
|
InitLookupTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultVideoFilter::InitConversionMatrix(double hueShift, double saturationShift)
|
void DefaultVideoFilter::InitConversionMatrix(double hueShift, double saturationShift)
|
||||||
{
|
{
|
||||||
_pictureSettings.Hue = hueShift;
|
|
||||||
_pictureSettings.Saturation = saturationShift;
|
|
||||||
|
|
||||||
double hue = hueShift * M_PI;
|
double hue = hueShift * M_PI;
|
||||||
double sat = saturationShift + 1;
|
double sat = saturationShift + 1;
|
||||||
|
|
||||||
|
@ -34,60 +33,40 @@ void DefaultVideoFilter::InitConversionMatrix(double hueShift, double saturation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultVideoFilter::OnBeforeApplyFilter()
|
void DefaultVideoFilter::InitLookupTable()
|
||||||
{
|
{
|
||||||
/*PictureSettings currentSettings = _console->GetSettings()->GetPictureSettings();
|
VideoConfig config = _console->GetSettings()->GetVideoConfig();
|
||||||
if(_pictureSettings.Hue != currentSettings.Hue || _pictureSettings.Saturation != currentSettings.Saturation) {
|
|
||||||
InitConversionMatrix(currentSettings.Hue, currentSettings.Saturation);
|
InitConversionMatrix(config.Hue, config.Saturation);
|
||||||
}
|
|
||||||
_pictureSettings = currentSettings;
|
|
||||||
_needToProcess = _pictureSettings.Hue != 0 || _pictureSettings.Saturation != 0 || _pictureSettings.Brightness || _pictureSettings.Contrast;
|
|
||||||
|
|
||||||
if(_needToProcess) {
|
|
||||||
double y, i, q;
|
double y, i, q;
|
||||||
uint32_t* originalPalette = _console->GetSettings()->GetRgbPalette();
|
for(int rgb555 = 0; rgb555 < 0x8000; rgb555++) {
|
||||||
|
double redChannel = To8Bit(rgb555 & 0x1F) / 255.0;
|
||||||
for(int pal = 0; pal < 512; pal++) {
|
double greenChannel = To8Bit((rgb555 >> 5) & 0x1F) / 255.0;
|
||||||
uint32_t pixelOutput = originalPalette[pal];
|
double blueChannel = To8Bit(rgb555 >> 10) / 255.0;
|
||||||
double redChannel = ((pixelOutput & 0xFF0000) >> 16) / 255.0;
|
|
||||||
double greenChannel = ((pixelOutput & 0xFF00) >> 8) / 255.0;
|
|
||||||
double blueChannel = (pixelOutput & 0xFF) / 255.0;
|
|
||||||
|
|
||||||
//Apply brightness, contrast, hue & saturation
|
//Apply brightness, contrast, hue & saturation
|
||||||
RgbToYiq(redChannel, greenChannel, blueChannel, y, i, q);
|
RgbToYiq(redChannel, greenChannel, blueChannel, y, i, q);
|
||||||
y *= _pictureSettings.Contrast * 0.5f + 1;
|
y *= config.Contrast * 0.5f + 1;
|
||||||
y += _pictureSettings.Brightness * 0.5f;
|
y += config.Brightness * 0.5f;
|
||||||
YiqToRgb(y, i, q, redChannel, greenChannel, blueChannel);
|
YiqToRgb(y, i, q, redChannel, greenChannel, blueChannel);
|
||||||
|
|
||||||
int r = std::min(255, (int)(redChannel * 255));
|
int r = std::min(255, (int)(redChannel * 255));
|
||||||
int g = std::min(255, (int)(greenChannel * 255));
|
int g = std::min(255, (int)(greenChannel * 255));
|
||||||
int b = std::min(255, (int)(blueChannel * 255));
|
int b = std::min(255, (int)(blueChannel * 255));
|
||||||
|
|
||||||
_calculatedPalette[pal] = 0xFF000000 | (r << 16) | (g << 8) | b;
|
_calculatedPalette[rgb555] = 0xFF000000 | (r << 16) | (g << 8) | b;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
memcpy(_calculatedPalette, _console->GetSettings()->GetRgbPalette(), sizeof(_calculatedPalette));
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultVideoFilter::DecodePpuBuffer(uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, bool displayScanlines)
|
_videoConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultVideoFilter::OnBeforeApplyFilter()
|
||||||
{
|
{
|
||||||
/*uint32_t* out = outputBuffer;
|
VideoConfig config = _console->GetSettings()->GetVideoConfig();
|
||||||
OverscanDimensions overscan = GetOverscan();
|
if(_videoConfig.Hue != config.Hue || _videoConfig.Saturation != config.Saturation || _videoConfig.Contrast != config.Contrast || _videoConfig.Brightness != config.Brightness) {
|
||||||
uint8_t scanlineIntensity = (uint8_t)((1.0 - _console->GetSettings()->GetPictureSettings().ScanlineIntensity) * 255);
|
InitLookupTable();
|
||||||
for(uint32_t i = overscan.Top, iMax = 240 - overscan.Bottom; i < iMax; i++) {
|
|
||||||
if(displayScanlines && (i + overscan.Top) % 2 == 0) {
|
|
||||||
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
|
|
||||||
*out = ApplyScanlineEffect(ppuOutputBuffer[i * 256 + j], scanlineIntensity);
|
|
||||||
out++;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
|
|
||||||
*out = _calculatedPalette[ppuOutputBuffer[i * 256 + j]];
|
|
||||||
out++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t DefaultVideoFilter::To8Bit(uint8_t color)
|
uint8_t DefaultVideoFilter::To8Bit(uint8_t color)
|
||||||
|
@ -107,10 +86,28 @@ uint32_t DefaultVideoFilter::ToArgb(uint16_t rgb555)
|
||||||
void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
|
void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
|
||||||
{
|
{
|
||||||
uint32_t *out = GetOutputBuffer();
|
uint32_t *out = GetOutputBuffer();
|
||||||
uint32_t pixelCount = GetFrameInfo().Width * GetFrameInfo().Height;
|
FrameInfo frameInfo = GetFrameInfo();
|
||||||
|
|
||||||
|
uint8_t scanlineIntensity = (uint8_t)((1.0 - _console->GetSettings()->GetVideoConfig().ScanlineIntensity) * 255);
|
||||||
|
if(scanlineIntensity < 255) {
|
||||||
|
for(uint32_t i = 0; i < frameInfo.Height; i++) {
|
||||||
|
if(i & 0x01) {
|
||||||
|
for(uint32_t j = 0; j < frameInfo.Width; j++) {
|
||||||
|
*out = ApplyScanlineEffect(_calculatedPalette[ppuOutputBuffer[i * 512 + j]], scanlineIntensity);
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(uint32_t j = 0; j < frameInfo.Width; j++) {
|
||||||
|
*out = _calculatedPalette[ppuOutputBuffer[i * 512 + j]];
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint32_t pixelCount = frameInfo.Width * frameInfo.Height;
|
||||||
for(uint32_t i = 0; i < pixelCount; i++) {
|
for(uint32_t i = 0; i < pixelCount; i++) {
|
||||||
out[i] = ToArgb(ppuOutputBuffer[i]);
|
out[i] = _calculatedPalette[ppuOutputBuffer[i]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,14 +124,3 @@ void DefaultVideoFilter::YiqToRgb(double y, double i, double q, double &r, doubl
|
||||||
g = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[2] * i + _yiqToRgbMatrix[3] * q)));
|
g = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[2] * i + _yiqToRgbMatrix[3] * q)));
|
||||||
b = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[4] * i + _yiqToRgbMatrix[5] * q)));
|
b = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[4] * i + _yiqToRgbMatrix[5] * q)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DefaultVideoFilter::ApplyScanlineEffect(uint16_t ppuPixel, uint8_t scanlineIntensity)
|
|
||||||
{
|
|
||||||
uint32_t pixelOutput = _calculatedPalette[ppuPixel];
|
|
||||||
|
|
||||||
uint8_t r = ((pixelOutput & 0xFF0000) >> 16) * scanlineIntensity / 255;
|
|
||||||
uint8_t g = ((pixelOutput & 0xFF00) >> 8) * scanlineIntensity / 255;
|
|
||||||
uint8_t b = (pixelOutput & 0xFF) * scanlineIntensity / 255;
|
|
||||||
|
|
||||||
return 0xFF000000 | (r << 16) | (g << 8) | b;
|
|
||||||
}
|
|
|
@ -2,24 +2,24 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "BaseVideoFilter.h"
|
#include "BaseVideoFilter.h"
|
||||||
|
#include "SettingTypes.h"
|
||||||
|
|
||||||
class DefaultVideoFilter : public BaseVideoFilter
|
class DefaultVideoFilter : public BaseVideoFilter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
uint32_t _calculatedPalette[0x8000];
|
||||||
double _yiqToRgbMatrix[6];
|
double _yiqToRgbMatrix[6];
|
||||||
uint32_t _calculatedPalette[512];
|
VideoConfig _videoConfig;
|
||||||
PictureSettings _pictureSettings;
|
|
||||||
bool _needToProcess = false;
|
bool _needToProcess = false;
|
||||||
|
|
||||||
void InitConversionMatrix(double hueShift, double saturationShift);
|
void InitConversionMatrix(double hueShift, double saturationShift);
|
||||||
|
void InitLookupTable();
|
||||||
|
|
||||||
void RgbToYiq(double r, double g, double b, double &y, double &i, double &q);
|
void RgbToYiq(double r, double g, double b, double &y, double &i, double &q);
|
||||||
void YiqToRgb(double y, double i, double q, double &r, double &g, double &b);
|
void YiqToRgb(double y, double i, double q, double &r, double &g, double &b);
|
||||||
__forceinline static uint8_t To8Bit(uint8_t color);
|
__forceinline static uint8_t To8Bit(uint8_t color);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DecodePpuBuffer(uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, bool displayScanlines);
|
|
||||||
uint32_t ApplyScanlineEffect(uint16_t ppuPixel, uint8_t scanlineIntensity);
|
|
||||||
void OnBeforeApplyFilter();
|
void OnBeforeApplyFilter();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
32
Core/EmuSettings.cpp
Normal file
32
Core/EmuSettings.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "EmuSettings.h"
|
||||||
|
|
||||||
|
void EmuSettings::SetVideoConfig(VideoConfig config)
|
||||||
|
{
|
||||||
|
_video = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoConfig EmuSettings::GetVideoConfig()
|
||||||
|
{
|
||||||
|
return _video;
|
||||||
|
}
|
||||||
|
|
||||||
|
double EmuSettings::GetAspectRatio()
|
||||||
|
{
|
||||||
|
switch(_video.AspectRatio) {
|
||||||
|
case VideoAspectRatio::NoStretching: return 0.0;
|
||||||
|
|
||||||
|
case VideoAspectRatio::Auto:
|
||||||
|
{
|
||||||
|
bool isPal = false;
|
||||||
|
return isPal ? (9440000.0 / 6384411.0) : (128.0 / 105.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
case VideoAspectRatio::NTSC: return 128.0 / 105.0;
|
||||||
|
case VideoAspectRatio::PAL: return 9440000.0 / 6384411.0;
|
||||||
|
case VideoAspectRatio::Standard: return 4.0 / 3.0;
|
||||||
|
case VideoAspectRatio::Widescreen: return 16.0 / 9.0;
|
||||||
|
case VideoAspectRatio::Custom: return _video.CustomAspectRatio;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
14
Core/EmuSettings.h
Normal file
14
Core/EmuSettings.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "SettingTypes.h"
|
||||||
|
|
||||||
|
class EmuSettings
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
VideoConfig _video;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetVideoConfig(VideoConfig config);
|
||||||
|
VideoConfig GetVideoConfig();
|
||||||
|
double GetAspectRatio();
|
||||||
|
};
|
72
Core/NtscFilter.cpp
Normal file
72
Core/NtscFilter.cpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "NtscFilter.h"
|
||||||
|
#include "EmuSettings.h"
|
||||||
|
#include "SettingTypes.h"
|
||||||
|
#include "Console.h"
|
||||||
|
|
||||||
|
NtscFilter::NtscFilter(shared_ptr<Console> console) : BaseVideoFilter(console)
|
||||||
|
{
|
||||||
|
memset(&_ntscData, 0, sizeof(_ntscData));
|
||||||
|
_ntscSetup = { };
|
||||||
|
snes_ntsc_init(&_ntscData, &_ntscSetup);
|
||||||
|
_ntscBuffer = new uint32_t[SNES_NTSC_OUT_WIDTH(256) * 480];
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameInfo NtscFilter::GetFrameInfo()
|
||||||
|
{
|
||||||
|
FrameInfo frameInfo = BaseVideoFilter::GetFrameInfo();
|
||||||
|
frameInfo.Width = SNES_NTSC_OUT_WIDTH(frameInfo.Width / 2);
|
||||||
|
return frameInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtscFilter::OnBeforeApplyFilter()
|
||||||
|
{
|
||||||
|
VideoConfig cfg = _console->GetSettings()->GetVideoConfig();
|
||||||
|
|
||||||
|
if(_ntscSetup.hue != cfg.Hue / 100.0 || _ntscSetup.saturation != cfg.Saturation / 100.0 || _ntscSetup.brightness != cfg.Brightness / 100.0 || _ntscSetup.contrast != cfg.Contrast / 100.0 ||
|
||||||
|
_ntscSetup.artifacts != cfg.NtscArtifacts || _ntscSetup.bleed != cfg.NtscBleed || _ntscSetup.fringing != cfg.NtscFringing || _ntscSetup.gamma != cfg.NtscGamma ||
|
||||||
|
(_ntscSetup.merge_fields == 1) != cfg.NtscMergeFields || _ntscSetup.resolution != cfg.NtscResolution || _ntscSetup.sharpness != cfg.NtscSharpness) {
|
||||||
|
_ntscSetup.hue = cfg.Hue;
|
||||||
|
_ntscSetup.saturation = cfg.Saturation;
|
||||||
|
_ntscSetup.brightness = cfg.Brightness;
|
||||||
|
_ntscSetup.contrast = cfg.Contrast;
|
||||||
|
|
||||||
|
_ntscSetup.artifacts = cfg.NtscArtifacts;
|
||||||
|
_ntscSetup.bleed = cfg.NtscBleed;
|
||||||
|
_ntscSetup.fringing = cfg.NtscFringing;
|
||||||
|
_ntscSetup.gamma = cfg.NtscGamma;
|
||||||
|
_ntscSetup.merge_fields = (int)cfg.NtscMergeFields;
|
||||||
|
_ntscSetup.resolution = cfg.NtscResolution;
|
||||||
|
_ntscSetup.sharpness = cfg.NtscSharpness;
|
||||||
|
snes_ntsc_init(&_ntscData, &_ntscSetup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
|
||||||
|
{
|
||||||
|
FrameInfo frameInfo = GetFrameInfo();
|
||||||
|
snes_ntsc_blit_hires(&_ntscData, ppuOutputBuffer, 512, IsOddFrame() ? 0 : 1, 512, frameInfo.Height, _ntscBuffer, SNES_NTSC_OUT_WIDTH(256)*4);
|
||||||
|
VideoConfig cfg = _console->GetSettings()->GetVideoConfig();
|
||||||
|
|
||||||
|
if(cfg.ScanlineIntensity == 0) {
|
||||||
|
memcpy(GetOutputBuffer(), _ntscBuffer, frameInfo.Width * frameInfo.Height * sizeof(uint32_t));
|
||||||
|
} else {
|
||||||
|
uint8_t intensity = (uint8_t)((1.0 - cfg.ScanlineIntensity) * 255);
|
||||||
|
for(uint32_t i = 0; i < frameInfo.Height; i++) {
|
||||||
|
if(i & 0x01) {
|
||||||
|
uint32_t *in = _ntscBuffer + i * frameInfo.Width;
|
||||||
|
uint32_t *out = GetOutputBuffer() + i * frameInfo.Width;
|
||||||
|
for(uint32_t j = 0; j < frameInfo.Width; j++) {
|
||||||
|
out[j] = ApplyScanlineEffect(in[j], intensity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(GetOutputBuffer()+i*frameInfo.Width, _ntscBuffer+i*frameInfo.Width, frameInfo.Width * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NtscFilter::~NtscFilter()
|
||||||
|
{
|
||||||
|
delete[] _ntscBuffer;
|
||||||
|
}
|
24
Core/NtscFilter.h
Normal file
24
Core/NtscFilter.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "BaseVideoFilter.h"
|
||||||
|
#include "../Utilities/snes_ntsc.h"
|
||||||
|
|
||||||
|
class Console;
|
||||||
|
|
||||||
|
class NtscFilter : public BaseVideoFilter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
snes_ntsc_setup_t _ntscSetup;
|
||||||
|
snes_ntsc_t _ntscData;
|
||||||
|
uint32_t* _ntscBuffer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnBeforeApplyFilter();
|
||||||
|
|
||||||
|
public:
|
||||||
|
NtscFilter(shared_ptr<Console> console);
|
||||||
|
virtual ~NtscFilter();
|
||||||
|
|
||||||
|
virtual void ApplyFilter(uint16_t *ppuOutputBuffer);
|
||||||
|
virtual FrameInfo GetFrameInfo();
|
||||||
|
};
|
141
Core/ScaleFilter.cpp
Normal file
141
Core/ScaleFilter.cpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "ScaleFilter.h"
|
||||||
|
#include "../Utilities/xBRZ/xbrz.h"
|
||||||
|
#include "../Utilities/HQX/hqx.h"
|
||||||
|
#include "../Utilities/Scale2x/scalebit.h"
|
||||||
|
#include "../Utilities/KreedSaiEagle/SaiEagle.h"
|
||||||
|
|
||||||
|
bool ScaleFilter::_hqxInitDone = false;
|
||||||
|
|
||||||
|
ScaleFilter::ScaleFilter(ScaleFilterType scaleFilterType, uint32_t scale)
|
||||||
|
{
|
||||||
|
_scaleFilterType = scaleFilterType;
|
||||||
|
_filterScale = scale;
|
||||||
|
|
||||||
|
if(!_hqxInitDone && _scaleFilterType == ScaleFilterType::HQX) {
|
||||||
|
hqxInit();
|
||||||
|
_hqxInitDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleFilter::~ScaleFilter()
|
||||||
|
{
|
||||||
|
if(_outputBuffer) {
|
||||||
|
delete[] _outputBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ScaleFilter::GetScale()
|
||||||
|
{
|
||||||
|
return _filterScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleFilter::ApplyPrescaleFilter(uint32_t *inputArgbBuffer)
|
||||||
|
{
|
||||||
|
uint32_t* outputBuffer = _outputBuffer;
|
||||||
|
|
||||||
|
for(uint32_t y = 0; y < _height; y++) {
|
||||||
|
for(uint32_t x = 0; x < _width; x++) {
|
||||||
|
for(uint32_t i = 0; i < _filterScale; i++) {
|
||||||
|
*(outputBuffer++) = *inputArgbBuffer;
|
||||||
|
}
|
||||||
|
inputArgbBuffer++;
|
||||||
|
}
|
||||||
|
for(uint32_t i = 1; i < _filterScale; i++) {
|
||||||
|
memcpy(outputBuffer, outputBuffer - _width*_filterScale, _width*_filterScale *4);
|
||||||
|
outputBuffer += _width*_filterScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleFilter::UpdateOutputBuffer(uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
if(!_outputBuffer || width != _width || height != _height) {
|
||||||
|
if(_outputBuffer) {
|
||||||
|
delete[] _outputBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
_outputBuffer = new uint32_t[_width*_height*_filterScale*_filterScale];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t* ScaleFilter::ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, uint32_t height, double scanlineIntensity)
|
||||||
|
{
|
||||||
|
UpdateOutputBuffer(width, height);
|
||||||
|
|
||||||
|
if(_scaleFilterType == ScaleFilterType::xBRZ) {
|
||||||
|
xbrz::scale(_filterScale, inputArgbBuffer, _outputBuffer, width, height, xbrz::ColorFormat::ARGB);
|
||||||
|
} else if(_scaleFilterType == ScaleFilterType::HQX) {
|
||||||
|
hqx(_filterScale, inputArgbBuffer, _outputBuffer, width, height);
|
||||||
|
} else if(_scaleFilterType == ScaleFilterType::Scale2x) {
|
||||||
|
scale(_filterScale, _outputBuffer, width*sizeof(uint32_t)*_filterScale, inputArgbBuffer, width*sizeof(uint32_t), 4, width, height);
|
||||||
|
} else if(_scaleFilterType == ScaleFilterType::_2xSai) {
|
||||||
|
twoxsai_generic_xrgb8888(width, height, inputArgbBuffer, width, _outputBuffer, width * _filterScale);
|
||||||
|
} else if(_scaleFilterType == ScaleFilterType::Super2xSai) {
|
||||||
|
supertwoxsai_generic_xrgb8888(width, height, inputArgbBuffer, width, _outputBuffer, width * _filterScale);
|
||||||
|
} else if(_scaleFilterType == ScaleFilterType::SuperEagle) {
|
||||||
|
supereagle_generic_xrgb8888(width, height, inputArgbBuffer, width, _outputBuffer, width * _filterScale);
|
||||||
|
} else if(_scaleFilterType == ScaleFilterType::Prescale) {
|
||||||
|
ApplyPrescaleFilter(inputArgbBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
scanlineIntensity = 1.0 - scanlineIntensity;
|
||||||
|
|
||||||
|
if(scanlineIntensity < 1.0) {
|
||||||
|
for(int y = 1, yMax = height * _filterScale; y < yMax; y += 2) {
|
||||||
|
for(int x = 0, xMax = width * _filterScale; x < xMax; x++) {
|
||||||
|
uint32_t &color = _outputBuffer[y*xMax + x];
|
||||||
|
uint8_t r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF;
|
||||||
|
r = (uint8_t)(r * scanlineIntensity);
|
||||||
|
g = (uint8_t)(g * scanlineIntensity);
|
||||||
|
b = (uint8_t)(b * scanlineIntensity);
|
||||||
|
color = 0xFF000000 | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _outputBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ScaleFilter> ScaleFilter::GetScaleFilter(VideoFilterType filter)
|
||||||
|
{
|
||||||
|
shared_ptr<ScaleFilter> scaleFilter;
|
||||||
|
switch(filter) {
|
||||||
|
case VideoFilterType::NTSC:
|
||||||
|
case VideoFilterType::None:
|
||||||
|
break;
|
||||||
|
|
||||||
|
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();
|
||||||
|
return info;
|
||||||
|
}
|
28
Core/ScaleFilter.h
Normal file
28
Core/ScaleFilter.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "DefaultVideoFilter.h"
|
||||||
|
|
||||||
|
class ScaleFilter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static bool _hqxInitDone;
|
||||||
|
uint32_t _filterScale;
|
||||||
|
ScaleFilterType _scaleFilterType;
|
||||||
|
uint32_t *_outputBuffer = nullptr;
|
||||||
|
uint32_t _width = 0;
|
||||||
|
uint32_t _height = 0;
|
||||||
|
|
||||||
|
void ApplyPrescaleFilter(uint32_t *inputArgbBuffer);
|
||||||
|
void UpdateOutputBuffer(uint32_t width, uint32_t height);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScaleFilter(ScaleFilterType scaleFilterType, uint32_t scale);
|
||||||
|
~ScaleFilter();
|
||||||
|
|
||||||
|
uint32_t GetScale();
|
||||||
|
uint32_t* ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, uint32_t height, double scanlineIntensity);
|
||||||
|
FrameInfo GetFrameInfo(FrameInfo baseFrameInfo);
|
||||||
|
|
||||||
|
static shared_ptr<ScaleFilter> GetScaleFilter(VideoFilterType filter);
|
||||||
|
};
|
|
@ -15,32 +15,27 @@ enum class ScaleFilterType
|
||||||
enum class VideoFilterType
|
enum class VideoFilterType
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
NTSC = 1,
|
NTSC,
|
||||||
BisqwitNtscQuarterRes = 2,
|
xBRZ2x,
|
||||||
BisqwitNtscHalfRes = 3,
|
xBRZ3x,
|
||||||
BisqwitNtsc = 4,
|
xBRZ4x,
|
||||||
xBRZ2x = 5,
|
xBRZ5x,
|
||||||
xBRZ3x = 6,
|
xBRZ6x,
|
||||||
xBRZ4x = 7,
|
HQ2x,
|
||||||
xBRZ5x = 8,
|
HQ3x,
|
||||||
xBRZ6x = 9,
|
HQ4x,
|
||||||
HQ2x = 10,
|
Scale2x,
|
||||||
HQ3x = 11,
|
Scale3x,
|
||||||
HQ4x = 12,
|
Scale4x,
|
||||||
Scale2x = 13,
|
_2xSai,
|
||||||
Scale3x = 14,
|
Super2xSai,
|
||||||
Scale4x = 15,
|
SuperEagle,
|
||||||
_2xSai = 16,
|
Prescale2x,
|
||||||
Super2xSai = 17,
|
Prescale3x,
|
||||||
SuperEagle = 18,
|
Prescale4x,
|
||||||
Prescale2x = 19,
|
Prescale6x,
|
||||||
Prescale3x = 20,
|
Prescale8x,
|
||||||
Prescale4x = 21,
|
Prescale10x
|
||||||
Prescale6x = 22,
|
|
||||||
Prescale8x = 23,
|
|
||||||
Prescale10x = 24,
|
|
||||||
Raw = 25,
|
|
||||||
HdPack = 999
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class VideoResizeFilter
|
enum class VideoResizeFilter
|
||||||
|
@ -60,6 +55,35 @@ enum class VideoAspectRatio
|
||||||
Custom = 6
|
Custom = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VideoConfig
|
||||||
|
{
|
||||||
|
double VideoScale = 2;
|
||||||
|
double CustomAspectRatio = 1.0;
|
||||||
|
VideoFilterType VideoFilter = VideoFilterType::NTSC;
|
||||||
|
VideoAspectRatio AspectRatio = VideoAspectRatio::NoStretching;
|
||||||
|
bool UseBilinearInterpolation = false;
|
||||||
|
bool VerticalSync = false;
|
||||||
|
bool IntegerFpsMode = false;
|
||||||
|
|
||||||
|
double Brightness = 0;
|
||||||
|
double Contrast = 0;
|
||||||
|
double Hue = 0;
|
||||||
|
double Saturation = 0;
|
||||||
|
double ScanlineIntensity = 0;
|
||||||
|
|
||||||
|
double NtscArtifacts = 0;
|
||||||
|
double NtscBleed = 0;
|
||||||
|
double NtscFringing = 0;
|
||||||
|
double NtscGamma = 0;
|
||||||
|
double NtscResolution = 0;
|
||||||
|
double NtscSharpness = 0;
|
||||||
|
bool NtscMergeFields = false;
|
||||||
|
|
||||||
|
bool FullscreenForceIntegerScale = false;
|
||||||
|
bool UseExclusiveFullscreen = false;
|
||||||
|
int32_t ExclusiveFullscreenRefreshRate = 60;
|
||||||
|
};
|
||||||
|
|
||||||
struct OverscanDimensions
|
struct OverscanDimensions
|
||||||
{
|
{
|
||||||
uint32_t Left = 0;
|
uint32_t Left = 0;
|
||||||
|
@ -68,32 +92,6 @@ struct OverscanDimensions
|
||||||
uint32_t Bottom = 0;
|
uint32_t Bottom = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PictureSettings
|
|
||||||
{
|
|
||||||
double Brightness = 0;
|
|
||||||
double Contrast = 0;
|
|
||||||
double Saturation = 0;
|
|
||||||
double Hue = 0;
|
|
||||||
double ScanlineIntensity = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NtscFilterSettings
|
|
||||||
{
|
|
||||||
double Sharpness = 0;
|
|
||||||
double Gamma = 0;
|
|
||||||
double Resolution = 0;
|
|
||||||
double Artifacts = 0;
|
|
||||||
double Fringing = 0;
|
|
||||||
double Bleed = 0;
|
|
||||||
bool MergeFields = false;
|
|
||||||
bool VerticalBlend = false;
|
|
||||||
bool KeepVerticalResolution = false;
|
|
||||||
|
|
||||||
double YFilterLength = 0;
|
|
||||||
double IFilterLength = 0;
|
|
||||||
double QFilterLength = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FrameInfo
|
struct FrameInfo
|
||||||
{
|
{
|
||||||
uint32_t Width;
|
uint32_t Width;
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
#include "VideoDecoder.h"
|
#include "VideoDecoder.h"
|
||||||
#include "VideoRenderer.h"
|
#include "VideoRenderer.h"
|
||||||
#include "DefaultVideoFilter.h"
|
#include "DefaultVideoFilter.h"
|
||||||
|
#include "NotificationManager.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
#include "EmuSettings.h"
|
||||||
|
#include "SettingTypes.h"
|
||||||
|
#include "NtscFilter.h"
|
||||||
|
#include "ScaleFilter.h"
|
||||||
#include "Ppu.h"
|
#include "Ppu.h"
|
||||||
#include "DebugHud.h"
|
#include "DebugHud.h"
|
||||||
|
|
||||||
|
@ -25,64 +30,40 @@ FrameInfo VideoDecoder::GetFrameInfo()
|
||||||
return _lastFrameInfo;
|
return _lastFrameInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoDecoder::GetScreenSize(ScreenSize &size, bool ignoreScale)
|
ScreenSize VideoDecoder::GetScreenSize(bool ignoreScale)
|
||||||
{
|
{
|
||||||
|
ScreenSize size = {};
|
||||||
if(_videoFilter) {
|
if(_videoFilter) {
|
||||||
/*OverscanDimensions overscan = ignoreScale ? _videoFilter->GetOverscan() : _console->GetSettings()->GetOverscanDimensions();
|
VideoConfig config = _console->GetSettings()->GetVideoConfig();
|
||||||
FrameInfo frameInfo{ overscan.GetScreenWidth(), overscan.GetScreenHeight(), PPU::ScreenWidth, PPU::ScreenHeight, 4 };
|
double aspectRatio = _console->GetSettings()->GetAspectRatio();
|
||||||
double aspectRatio = _console->GetSettings()->GetAspectRatio(_console);
|
double scale = (ignoreScale ? 1 : config.VideoScale);
|
||||||
double scale = (ignoreScale ? 1 : _console->GetSettings()->GetVideoScale());
|
size.Width = (int32_t)(_baseFrameInfo.Width * scale / 2);
|
||||||
size.Width = (int32_t)(frameInfo.Width * scale);
|
size.Height = (int32_t)(_baseFrameInfo.Height * scale / 2);
|
||||||
size.Height = (int32_t)(frameInfo.Height * scale);
|
size.Scale = scale;
|
||||||
if(aspectRatio != 0.0) {
|
if(aspectRatio != 0.0) {
|
||||||
size.Width = (uint32_t)(frameInfo.OriginalHeight * scale * aspectRatio * ((double)frameInfo.Width / frameInfo.OriginalWidth));
|
size.Width = (uint32_t)(_baseFrameInfo.Height * scale * aspectRatio / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_console->GetSettings()->GetScreenRotation() % 180) {
|
/*if(_console->GetSettings()->GetScreenRotation() % 180) {
|
||||||
std::swap(size.Width, size.Height);
|
std::swap(size.Width, size.Height);
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
return size;
|
||||||
size.Scale = scale;*/
|
|
||||||
|
|
||||||
size.Scale = 2;
|
|
||||||
if(ignoreScale) {
|
|
||||||
size.Width = _baseFrameInfo.Width;
|
|
||||||
size.Height = _baseFrameInfo.Height;
|
|
||||||
} else {
|
|
||||||
if(_baseFrameInfo.Width == 256) {
|
|
||||||
size.Width = (int32_t)(_baseFrameInfo.Width * size.Scale);
|
|
||||||
size.Height = (int32_t)(_baseFrameInfo.Height * size.Scale);
|
|
||||||
} else {
|
|
||||||
size.Width = (int32_t)_baseFrameInfo.Width;
|
|
||||||
size.Height = (int32_t)_baseFrameInfo.Height;
|
|
||||||
if(_baseFrameInfo.Height <= 240) {
|
|
||||||
size.Height *= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoDecoder::UpdateVideoFilter()
|
void VideoDecoder::UpdateVideoFilter()
|
||||||
{
|
{
|
||||||
VideoFilterType newFilter = VideoFilterType::None;
|
VideoFilterType newFilter = _console->GetSettings()->GetVideoConfig().VideoFilter;
|
||||||
|
|
||||||
if(_videoFilterType != newFilter || _videoFilter == nullptr) {
|
if(_videoFilterType != newFilter || _videoFilter == nullptr) {
|
||||||
_videoFilterType = newFilter;
|
_videoFilterType = newFilter;
|
||||||
_videoFilter.reset(new DefaultVideoFilter(_console));
|
_videoFilter.reset(new DefaultVideoFilter(_console));
|
||||||
//_scaleFilter.reset();
|
_scaleFilter.reset();
|
||||||
|
|
||||||
switch(_videoFilterType) {
|
switch(_videoFilterType) {
|
||||||
case VideoFilterType::None: break;
|
case VideoFilterType::None: break;
|
||||||
|
|
||||||
//TODO
|
|
||||||
/*
|
|
||||||
case VideoFilterType::NTSC: _videoFilter.reset(new NtscFilter(_console)); break;
|
case VideoFilterType::NTSC: _videoFilter.reset(new NtscFilter(_console)); break;
|
||||||
case VideoFilterType::BisqwitNtsc: _videoFilter.reset(new BisqwitNtscFilter(_console, 1)); break;
|
default: _scaleFilter = ScaleFilter::GetScaleFilter(_videoFilterType); break;
|
||||||
case VideoFilterType::BisqwitNtscHalfRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 2)); break;
|
|
||||||
case VideoFilterType::BisqwitNtscQuarterRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 4)); break;
|
|
||||||
case VideoFilterType::Raw: _videoFilter.reset(new RawVideoFilter(_console)); break;
|
|
||||||
default: _scaleFilter = ScaleFilter::GetScaleFilter(_videoFilterType); break;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,23 +93,24 @@ void VideoDecoder::DecodeFrame(bool synchronous)
|
||||||
if(_rotateFilter) {
|
if(_rotateFilter) {
|
||||||
outputBuffer = _rotateFilter->ApplyFilter(outputBuffer, frameInfo.Width, frameInfo.Height);
|
outputBuffer = _rotateFilter->ApplyFilter(outputBuffer, frameInfo.Width, frameInfo.Height);
|
||||||
frameInfo = _rotateFilter->GetFrameInfo(frameInfo);
|
frameInfo = _rotateFilter->GetFrameInfo(frameInfo);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if(_scaleFilter) {
|
if(_scaleFilter) {
|
||||||
outputBuffer = _scaleFilter->ApplyFilter(outputBuffer, frameInfo.Width, frameInfo.Height, _console->GetSettings()->GetPictureSettings().ScanlineIntensity);
|
outputBuffer = _scaleFilter->ApplyFilter(outputBuffer, frameInfo.Width, frameInfo.Height, _console->GetSettings()->GetVideoConfig().ScanlineIntensity);
|
||||||
frameInfo = _scaleFilter->GetFrameInfo(frameInfo);
|
frameInfo = _scaleFilter->GetFrameInfo(frameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if(_hud) {
|
if(_hud) {
|
||||||
_hud->DrawHud(_console, outputBuffer, frameInfo, _videoFilter->GetOverscan());
|
_hud->DrawHud(_console, outputBuffer, frameInfo, _videoFilter->GetOverscan());
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
ScreenSize screenSize;
|
ScreenSize screenSize = GetScreenSize(true);
|
||||||
GetScreenSize(screenSize, true);
|
VideoConfig config = _console->GetSettings()->GetVideoConfig();
|
||||||
/*if(_previousScale != _console->GetSettings()->GetVideoScale() || screenSize.Height != _previousScreenSize.Height || screenSize.Width != _previousScreenSize.Width) {
|
if(_previousScale != config.VideoScale || screenSize.Height != _previousScreenSize.Height || screenSize.Width != _previousScreenSize.Width) {
|
||||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::ResolutionChanged);
|
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::ResolutionChanged);
|
||||||
}*/
|
}
|
||||||
_previousScale = 1; // _console->GetSettings()->GetVideoScale();
|
_previousScale = config.VideoScale;
|
||||||
_previousScreenSize = screenSize;
|
_previousScreenSize = screenSize;
|
||||||
_lastFrameInfo = frameInfo;
|
_lastFrameInfo = frameInfo;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "SettingTypes.h"
|
#include "SettingTypes.h"
|
||||||
|
|
||||||
class BaseVideoFilter;
|
class BaseVideoFilter;
|
||||||
//class ScaleFilter;
|
class ScaleFilter;
|
||||||
//class RotateFilter;
|
//class RotateFilter;
|
||||||
class IRenderingDevice;
|
class IRenderingDevice;
|
||||||
//class VideoHud;
|
//class VideoHud;
|
||||||
|
@ -35,7 +35,7 @@ private:
|
||||||
|
|
||||||
VideoFilterType _videoFilterType = VideoFilterType::None;
|
VideoFilterType _videoFilterType = VideoFilterType::None;
|
||||||
unique_ptr<BaseVideoFilter> _videoFilter;
|
unique_ptr<BaseVideoFilter> _videoFilter;
|
||||||
//shared_ptr<ScaleFilter> _scaleFilter;
|
shared_ptr<ScaleFilter> _scaleFilter;
|
||||||
//shared_ptr<RotateFilter> _rotateFilter;
|
//shared_ptr<RotateFilter> _rotateFilter;
|
||||||
|
|
||||||
void UpdateVideoFilter();
|
void UpdateVideoFilter();
|
||||||
|
@ -53,7 +53,7 @@ public:
|
||||||
uint32_t GetFrameCount();
|
uint32_t GetFrameCount();
|
||||||
|
|
||||||
FrameInfo GetFrameInfo();
|
FrameInfo GetFrameInfo();
|
||||||
void GetScreenSize(ScreenSize &size, bool ignoreScale);
|
ScreenSize GetScreenSize(bool ignoreScale);
|
||||||
|
|
||||||
void UpdateFrameSync(uint16_t *ppuOutputBuffer, uint16_t width, uint16_t height, uint32_t frameNumber);
|
void UpdateFrameSync(uint16_t *ppuOutputBuffer, uint16_t width, uint16_t height, uint32_t frameNumber);
|
||||||
void UpdateFrame(uint16_t *ppuOutputBuffer, uint16_t width, uint16_t height, uint32_t frameNumber);
|
void UpdateFrame(uint16_t *ppuOutputBuffer, uint16_t width, uint16_t height, uint32_t frameNumber);
|
||||||
|
|
13
InteropDLL/ConfigApiWrapper.cpp
Normal file
13
InteropDLL/ConfigApiWrapper.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "../Core/Console.h"
|
||||||
|
#include "../Core/EmuSettings.h"
|
||||||
|
#include "../Core/SettingTypes.h"
|
||||||
|
|
||||||
|
extern shared_ptr<Console> _console;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
DllExport void __stdcall SetVideoConfig(VideoConfig config)
|
||||||
|
{
|
||||||
|
_console->GetSettings()->SetVideoConfig(config);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "../Core/Console.h"
|
#include "../Core/Console.h"
|
||||||
|
#include "../Core/VideoDecoder.h"
|
||||||
#include "../Core/MessageManager.h"
|
#include "../Core/MessageManager.h"
|
||||||
#include "../Core/INotificationListener.h"
|
#include "../Core/INotificationListener.h"
|
||||||
#include "../Core/KeyManager.h"
|
#include "../Core/KeyManager.h"
|
||||||
|
@ -28,7 +29,6 @@ string _logString;
|
||||||
shared_ptr<Console> _console;
|
shared_ptr<Console> _console;
|
||||||
InteropNotificationListeners _listeners;
|
InteropNotificationListeners _listeners;
|
||||||
|
|
||||||
namespace InteropEmu {
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
DllExport bool __stdcall TestDll()
|
DllExport bool __stdcall TestDll()
|
||||||
{
|
{
|
||||||
|
@ -183,6 +183,11 @@ namespace InteropEmu {
|
||||||
return _logString.c_str();
|
return _logString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DllExport ScreenSize __stdcall GetScreenSize(bool ignoreScale)
|
||||||
|
{
|
||||||
|
return _console->GetVideoDecoder()->GetScreenSize(ignoreScale);
|
||||||
|
}
|
||||||
|
|
||||||
DllExport void __stdcall WriteLogEntry(char* message) { MessageManager::Log(message); }
|
DllExport void __stdcall WriteLogEntry(char* message) { MessageManager::Log(message); }
|
||||||
|
|
||||||
DllExport void __stdcall PgoRunTest(vector<string> testRoms, bool enableDebugger)
|
DllExport void __stdcall PgoRunTest(vector<string> testRoms, bool enableDebugger)
|
||||||
|
@ -206,4 +211,3 @@ namespace InteropEmu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -453,6 +453,7 @@
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ConfigApiWrapper.cpp" />
|
||||||
<ClCompile Include="EmuApiWrapper.cpp" />
|
<ClCompile Include="EmuApiWrapper.cpp" />
|
||||||
<ClCompile Include="DebugApiWrapper.cpp" />
|
<ClCompile Include="DebugApiWrapper.cpp" />
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
|
|
@ -31,5 +31,8 @@
|
||||||
<ClCompile Include="EmuApiWrapper.cpp">
|
<ClCompile Include="EmuApiWrapper.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ConfigApiWrapper.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
18
UI/Config/BaseConfig.cs
Normal file
18
UI/Config/BaseConfig.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Mesen.GUI.Config
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public class BaseConfig<T>
|
||||||
|
{
|
||||||
|
public T Clone()
|
||||||
|
{
|
||||||
|
return (T)this.MemberwiseClone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ namespace Mesen.GUI.Config
|
||||||
|
|
||||||
public string Version = "0.1.0";
|
public string Version = "0.1.0";
|
||||||
public List<RecentItem> RecentFiles;
|
public List<RecentItem> RecentFiles;
|
||||||
|
public VideoConfig Video;
|
||||||
public DebugInfo Debug;
|
public DebugInfo Debug;
|
||||||
public Point? WindowLocation;
|
public Point? WindowLocation;
|
||||||
public Size? WindowSize;
|
public Size? WindowSize;
|
||||||
|
@ -25,6 +26,7 @@ namespace Mesen.GUI.Config
|
||||||
{
|
{
|
||||||
RecentFiles = new List<RecentItem>();
|
RecentFiles = new List<RecentItem>();
|
||||||
Debug = new DebugInfo();
|
Debug = new DebugInfo();
|
||||||
|
Video = new VideoConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
~Configuration()
|
~Configuration()
|
||||||
|
@ -50,6 +52,7 @@ namespace Mesen.GUI.Config
|
||||||
|
|
||||||
public void ApplyConfig()
|
public void ApplyConfig()
|
||||||
{
|
{
|
||||||
|
Video.ApplyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeDefaults()
|
public void InitializeDefaults()
|
||||||
|
|
82
UI/Config/VideoConfig.cs
Normal file
82
UI/Config/VideoConfig.cs
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Mesen.GUI.Config
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public class VideoConfig : BaseConfig<VideoConfig>
|
||||||
|
{
|
||||||
|
[MinMax(0.1, 10.0)] public double VideoScale = 2;
|
||||||
|
[MinMax(0.1, 5.0)] public double CustomAspectRatio = 1.0;
|
||||||
|
public VideoFilterType VideoFilter = VideoFilterType.None;
|
||||||
|
public VideoAspectRatio AspectRatio = VideoAspectRatio.NoStretching;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.I1)] public bool UseBilinearInterpolation = false;
|
||||||
|
[MarshalAs(UnmanagedType.I1)] public bool VerticalSync = false;
|
||||||
|
[MarshalAs(UnmanagedType.I1)] public bool IntegerFpsMode = false;
|
||||||
|
|
||||||
|
[MinMax(-1, 1.0)] public double Brightness = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double Contrast = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double Hue = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double Saturation = 0;
|
||||||
|
[MinMax(0, 1.0)] public double ScanlineIntensity = 0;
|
||||||
|
|
||||||
|
[MinMax(-1, 1.0)] public double NtscArtifacts = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double NtscBleed = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double NtscFringing = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double NtscGamma = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double NtscResolution = 0;
|
||||||
|
[MinMax(-1, 1.0)] public double NtscSharpness = 0;
|
||||||
|
[MarshalAs(UnmanagedType.I1)] public bool NtscMergeFields = false;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.I1)] public bool FullscreenForceIntegerScale = false;
|
||||||
|
[MarshalAs(UnmanagedType.I1)] public bool UseExclusiveFullscreen = false;
|
||||||
|
public Int32 ExclusiveFullscreenRefreshRate = 60;
|
||||||
|
|
||||||
|
public void ApplyConfig()
|
||||||
|
{
|
||||||
|
ConfigApi.SetVideoConfig(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum VideoFilterType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
NTSC,
|
||||||
|
xBRZ2x,
|
||||||
|
xBRZ3x,
|
||||||
|
xBRZ4x,
|
||||||
|
xBRZ5x,
|
||||||
|
xBRZ6x,
|
||||||
|
HQ2x,
|
||||||
|
HQ3x,
|
||||||
|
HQ4x,
|
||||||
|
Scale2x,
|
||||||
|
Scale3x,
|
||||||
|
Scale4x,
|
||||||
|
_2xSai,
|
||||||
|
Super2xSai,
|
||||||
|
SuperEagle,
|
||||||
|
Prescale2x,
|
||||||
|
Prescale3x,
|
||||||
|
Prescale4x,
|
||||||
|
Prescale6x,
|
||||||
|
Prescale8x,
|
||||||
|
Prescale10x
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum VideoAspectRatio
|
||||||
|
{
|
||||||
|
NoStretching = 0,
|
||||||
|
Auto = 1,
|
||||||
|
NTSC = 2,
|
||||||
|
PAL = 3,
|
||||||
|
Standard = 4,
|
||||||
|
Widescreen = 5,
|
||||||
|
Custom = 6
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,11 +74,7 @@ namespace Mesen.GUI.Forms
|
||||||
if(this.DialogResult == System.Windows.Forms.DialogResult.OK) {
|
if(this.DialogResult == System.Windows.Forms.DialogResult.OK) {
|
||||||
UpdateObject();
|
UpdateObject();
|
||||||
if(ApplyChangesOnOK) {
|
if(ApplyChangesOnOK) {
|
||||||
ConfigManager.ApplyChanges();
|
OnApply();
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(ApplyChangesOnOK) {
|
|
||||||
ConfigManager.RejectChanges();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
base.OnFormClosed(e);
|
base.OnFormClosed(e);
|
||||||
|
@ -89,6 +85,9 @@ namespace Mesen.GUI.Forms
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void OnApply()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void UpdateConfig()
|
protected virtual void UpdateConfig()
|
||||||
{
|
{
|
||||||
|
|
900
UI/Forms/Config/frmVideoConfig.Designer.cs
generated
Normal file
900
UI/Forms/Config/frmVideoConfig.Designer.cs
generated
Normal file
|
@ -0,0 +1,900 @@
|
||||||
|
namespace Mesen.GUI.Forms.Config
|
||||||
|
{
|
||||||
|
partial class frmVideoConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if(disposing && (components != null)) {
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
this.tabMain = new System.Windows.Forms.TabControl();
|
||||||
|
this.tpgGeneral = new System.Windows.Forms.TabPage();
|
||||||
|
this.tlpMain = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.chkUseExclusiveFullscreen = new System.Windows.Forms.CheckBox();
|
||||||
|
this.lblVideoScale = new System.Windows.Forms.Label();
|
||||||
|
this.chkVerticalSync = new System.Windows.Forms.CheckBox();
|
||||||
|
this.lblDisplayRatio = new System.Windows.Forms.Label();
|
||||||
|
this.nudScale = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||||
|
this.flowLayoutPanel6 = new System.Windows.Forms.FlowLayoutPanel();
|
||||||
|
this.cboAspectRatio = new System.Windows.Forms.ComboBox();
|
||||||
|
this.lblCustomRatio = new System.Windows.Forms.Label();
|
||||||
|
this.nudCustomRatio = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||||
|
this.chkFullscreenForceIntegerScale = new System.Windows.Forms.CheckBox();
|
||||||
|
this.chkShowFps = new System.Windows.Forms.CheckBox();
|
||||||
|
this.chkIntegerFpsMode = new System.Windows.Forms.CheckBox();
|
||||||
|
this.flpRefreshRate = new System.Windows.Forms.FlowLayoutPanel();
|
||||||
|
this.lblRequestedRefreshRate = new System.Windows.Forms.Label();
|
||||||
|
this.cboRefreshRate = new System.Windows.Forms.ComboBox();
|
||||||
|
this.tpgPicture = new System.Windows.Forms.TabPage();
|
||||||
|
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.btnSelectPreset = new System.Windows.Forms.Button();
|
||||||
|
this.btnResetPictureSettings = new System.Windows.Forms.Button();
|
||||||
|
this.grpNtscFilter = new System.Windows.Forms.GroupBox();
|
||||||
|
this.tlpNtscFilter = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.chkMergeFields = new System.Windows.Forms.CheckBox();
|
||||||
|
this.trkArtifacts = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkBleed = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkFringing = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkGamma = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkResolution = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkSharpness = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.grpCommon = new System.Windows.Forms.GroupBox();
|
||||||
|
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.chkBilinearInterpolation = new System.Windows.Forms.CheckBox();
|
||||||
|
this.trkBrightness = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkContrast = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkHue = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.trkSaturation = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.grpScanlines = new System.Windows.Forms.GroupBox();
|
||||||
|
this.trkScanlines = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
|
||||||
|
this.tableLayoutPanel8 = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.cboFilter = new System.Windows.Forms.ComboBox();
|
||||||
|
this.lblVideoFilter = new System.Windows.Forms.Label();
|
||||||
|
this.ctxPicturePresets = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||||
|
this.mnuPresetComposite = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuPresetSVideo = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuPresetRgb = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuPresetMonochrome = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.tabMain.SuspendLayout();
|
||||||
|
this.tpgGeneral.SuspendLayout();
|
||||||
|
this.tlpMain.SuspendLayout();
|
||||||
|
this.flowLayoutPanel6.SuspendLayout();
|
||||||
|
this.flpRefreshRate.SuspendLayout();
|
||||||
|
this.tpgPicture.SuspendLayout();
|
||||||
|
this.tableLayoutPanel5.SuspendLayout();
|
||||||
|
this.tableLayoutPanel7.SuspendLayout();
|
||||||
|
this.grpNtscFilter.SuspendLayout();
|
||||||
|
this.tlpNtscFilter.SuspendLayout();
|
||||||
|
this.grpCommon.SuspendLayout();
|
||||||
|
this.tableLayoutPanel4.SuspendLayout();
|
||||||
|
this.grpScanlines.SuspendLayout();
|
||||||
|
this.tableLayoutPanel8.SuspendLayout();
|
||||||
|
this.ctxPicturePresets.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// baseConfigPanel
|
||||||
|
//
|
||||||
|
this.baseConfigPanel.Location = new System.Drawing.Point(0, 408);
|
||||||
|
this.baseConfigPanel.Size = new System.Drawing.Size(574, 29);
|
||||||
|
//
|
||||||
|
// tabMain
|
||||||
|
//
|
||||||
|
this.tabMain.Controls.Add(this.tpgGeneral);
|
||||||
|
this.tabMain.Controls.Add(this.tpgPicture);
|
||||||
|
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tabMain.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.tabMain.Name = "tabMain";
|
||||||
|
this.tabMain.SelectedIndex = 0;
|
||||||
|
this.tabMain.Size = new System.Drawing.Size(574, 408);
|
||||||
|
this.tabMain.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// tpgGeneral
|
||||||
|
//
|
||||||
|
this.tpgGeneral.Controls.Add(this.tlpMain);
|
||||||
|
this.tpgGeneral.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tpgGeneral.Name = "tpgGeneral";
|
||||||
|
this.tpgGeneral.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tpgGeneral.Size = new System.Drawing.Size(566, 382);
|
||||||
|
this.tpgGeneral.TabIndex = 5;
|
||||||
|
this.tpgGeneral.Text = "General";
|
||||||
|
this.tpgGeneral.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tlpMain
|
||||||
|
//
|
||||||
|
this.tlpMain.ColumnCount = 2;
|
||||||
|
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||||
|
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tlpMain.Controls.Add(this.chkUseExclusiveFullscreen, 0, 4);
|
||||||
|
this.tlpMain.Controls.Add(this.lblVideoScale, 0, 0);
|
||||||
|
this.tlpMain.Controls.Add(this.chkVerticalSync, 0, 3);
|
||||||
|
this.tlpMain.Controls.Add(this.lblDisplayRatio, 0, 1);
|
||||||
|
this.tlpMain.Controls.Add(this.nudScale, 1, 0);
|
||||||
|
this.tlpMain.Controls.Add(this.flowLayoutPanel6, 1, 1);
|
||||||
|
this.tlpMain.Controls.Add(this.chkFullscreenForceIntegerScale, 0, 6);
|
||||||
|
this.tlpMain.Controls.Add(this.chkShowFps, 0, 7);
|
||||||
|
this.tlpMain.Controls.Add(this.chkIntegerFpsMode, 0, 2);
|
||||||
|
this.tlpMain.Controls.Add(this.flpRefreshRate, 0, 5);
|
||||||
|
this.tlpMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tlpMain.Location = new System.Drawing.Point(3, 3);
|
||||||
|
this.tlpMain.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.tlpMain.Name = "tlpMain";
|
||||||
|
this.tlpMain.RowCount = 9;
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||||
|
this.tlpMain.Size = new System.Drawing.Size(560, 376);
|
||||||
|
this.tlpMain.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// chkUseExclusiveFullscreen
|
||||||
|
//
|
||||||
|
this.chkUseExclusiveFullscreen.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.chkUseExclusiveFullscreen.AutoSize = true;
|
||||||
|
this.tlpMain.SetColumnSpan(this.chkUseExclusiveFullscreen, 2);
|
||||||
|
this.chkUseExclusiveFullscreen.Location = new System.Drawing.Point(3, 96);
|
||||||
|
this.chkUseExclusiveFullscreen.Name = "chkUseExclusiveFullscreen";
|
||||||
|
this.chkUseExclusiveFullscreen.Size = new System.Drawing.Size(169, 17);
|
||||||
|
this.chkUseExclusiveFullscreen.TabIndex = 24;
|
||||||
|
this.chkUseExclusiveFullscreen.Text = "Use exclusive fullscreen mode";
|
||||||
|
this.chkUseExclusiveFullscreen.UseVisualStyleBackColor = true;
|
||||||
|
this.chkUseExclusiveFullscreen.Visible = false;
|
||||||
|
//
|
||||||
|
// lblVideoScale
|
||||||
|
//
|
||||||
|
this.lblVideoScale.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.lblVideoScale.AutoSize = true;
|
||||||
|
this.lblVideoScale.Location = new System.Drawing.Point(3, 4);
|
||||||
|
this.lblVideoScale.Name = "lblVideoScale";
|
||||||
|
this.lblVideoScale.Size = new System.Drawing.Size(37, 13);
|
||||||
|
this.lblVideoScale.TabIndex = 11;
|
||||||
|
this.lblVideoScale.Text = "Scale:";
|
||||||
|
//
|
||||||
|
// chkVerticalSync
|
||||||
|
//
|
||||||
|
this.chkVerticalSync.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.chkVerticalSync.AutoSize = true;
|
||||||
|
this.tlpMain.SetColumnSpan(this.chkVerticalSync, 2);
|
||||||
|
this.chkVerticalSync.Location = new System.Drawing.Point(3, 73);
|
||||||
|
this.chkVerticalSync.Name = "chkVerticalSync";
|
||||||
|
this.chkVerticalSync.Size = new System.Drawing.Size(121, 17);
|
||||||
|
this.chkVerticalSync.TabIndex = 15;
|
||||||
|
this.chkVerticalSync.Text = "Enable vertical sync";
|
||||||
|
this.chkVerticalSync.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// lblDisplayRatio
|
||||||
|
//
|
||||||
|
this.lblDisplayRatio.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.lblDisplayRatio.AutoSize = true;
|
||||||
|
this.lblDisplayRatio.Location = new System.Drawing.Point(3, 27);
|
||||||
|
this.lblDisplayRatio.Name = "lblDisplayRatio";
|
||||||
|
this.lblDisplayRatio.Size = new System.Drawing.Size(71, 13);
|
||||||
|
this.lblDisplayRatio.TabIndex = 17;
|
||||||
|
this.lblDisplayRatio.Text = "Aspect Ratio:";
|
||||||
|
//
|
||||||
|
// nudScale
|
||||||
|
//
|
||||||
|
this.nudScale.DecimalPlaces = 2;
|
||||||
|
this.nudScale.Increment = new decimal(new int[] {
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0});
|
||||||
|
this.nudScale.Location = new System.Drawing.Point(77, 0);
|
||||||
|
this.nudScale.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.nudScale.Maximum = new decimal(new int[] {
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0});
|
||||||
|
this.nudScale.MaximumSize = new System.Drawing.Size(10000, 20);
|
||||||
|
this.nudScale.Minimum = new decimal(new int[] {
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
65536});
|
||||||
|
this.nudScale.MinimumSize = new System.Drawing.Size(0, 21);
|
||||||
|
this.nudScale.Name = "nudScale";
|
||||||
|
this.nudScale.Size = new System.Drawing.Size(48, 21);
|
||||||
|
this.nudScale.TabIndex = 21;
|
||||||
|
this.nudScale.Value = new decimal(new int[] {
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0});
|
||||||
|
//
|
||||||
|
// flowLayoutPanel6
|
||||||
|
//
|
||||||
|
this.flowLayoutPanel6.Controls.Add(this.cboAspectRatio);
|
||||||
|
this.flowLayoutPanel6.Controls.Add(this.lblCustomRatio);
|
||||||
|
this.flowLayoutPanel6.Controls.Add(this.nudCustomRatio);
|
||||||
|
this.flowLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.flowLayoutPanel6.Location = new System.Drawing.Point(77, 21);
|
||||||
|
this.flowLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.flowLayoutPanel6.Name = "flowLayoutPanel6";
|
||||||
|
this.flowLayoutPanel6.Size = new System.Drawing.Size(483, 26);
|
||||||
|
this.flowLayoutPanel6.TabIndex = 22;
|
||||||
|
//
|
||||||
|
// cboAspectRatio
|
||||||
|
//
|
||||||
|
this.cboAspectRatio.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cboAspectRatio.FormattingEnabled = true;
|
||||||
|
this.cboAspectRatio.Items.AddRange(new object[] {
|
||||||
|
"Auto",
|
||||||
|
"NTSC (8:7)",
|
||||||
|
"PAL (18:13)",
|
||||||
|
"Standard (4:3)",
|
||||||
|
"Widescreen (16:9)"});
|
||||||
|
this.cboAspectRatio.Location = new System.Drawing.Point(3, 3);
|
||||||
|
this.cboAspectRatio.Name = "cboAspectRatio";
|
||||||
|
this.cboAspectRatio.Size = new System.Drawing.Size(197, 21);
|
||||||
|
this.cboAspectRatio.TabIndex = 16;
|
||||||
|
//
|
||||||
|
// lblCustomRatio
|
||||||
|
//
|
||||||
|
this.lblCustomRatio.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.lblCustomRatio.AutoSize = true;
|
||||||
|
this.lblCustomRatio.Location = new System.Drawing.Point(206, 7);
|
||||||
|
this.lblCustomRatio.Name = "lblCustomRatio";
|
||||||
|
this.lblCustomRatio.Size = new System.Drawing.Size(76, 13);
|
||||||
|
this.lblCustomRatio.TabIndex = 17;
|
||||||
|
this.lblCustomRatio.Text = "Custom Ratio: ";
|
||||||
|
this.lblCustomRatio.Visible = false;
|
||||||
|
//
|
||||||
|
// nudCustomRatio
|
||||||
|
//
|
||||||
|
this.nudCustomRatio.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.nudCustomRatio.DecimalPlaces = 3;
|
||||||
|
this.nudCustomRatio.Increment = new decimal(new int[] {
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
65536});
|
||||||
|
this.nudCustomRatio.Location = new System.Drawing.Point(285, 3);
|
||||||
|
this.nudCustomRatio.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.nudCustomRatio.Maximum = new decimal(new int[] {
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0});
|
||||||
|
this.nudCustomRatio.MaximumSize = new System.Drawing.Size(10000, 20);
|
||||||
|
this.nudCustomRatio.Minimum = new decimal(new int[] {
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
65536});
|
||||||
|
this.nudCustomRatio.MinimumSize = new System.Drawing.Size(0, 21);
|
||||||
|
this.nudCustomRatio.Name = "nudCustomRatio";
|
||||||
|
this.nudCustomRatio.Size = new System.Drawing.Size(48, 21);
|
||||||
|
this.nudCustomRatio.TabIndex = 22;
|
||||||
|
this.nudCustomRatio.Value = new decimal(new int[] {
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
65536});
|
||||||
|
this.nudCustomRatio.Visible = false;
|
||||||
|
//
|
||||||
|
// chkFullscreenForceIntegerScale
|
||||||
|
//
|
||||||
|
this.chkFullscreenForceIntegerScale.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.chkFullscreenForceIntegerScale.AutoSize = true;
|
||||||
|
this.tlpMain.SetColumnSpan(this.chkFullscreenForceIntegerScale, 2);
|
||||||
|
this.chkFullscreenForceIntegerScale.Location = new System.Drawing.Point(3, 146);
|
||||||
|
this.chkFullscreenForceIntegerScale.Name = "chkFullscreenForceIntegerScale";
|
||||||
|
this.chkFullscreenForceIntegerScale.Size = new System.Drawing.Size(289, 17);
|
||||||
|
this.chkFullscreenForceIntegerScale.TabIndex = 23;
|
||||||
|
this.chkFullscreenForceIntegerScale.Text = "Use integer scale values when entering fullscreen mode";
|
||||||
|
this.chkFullscreenForceIntegerScale.UseVisualStyleBackColor = true;
|
||||||
|
this.chkFullscreenForceIntegerScale.Visible = false;
|
||||||
|
//
|
||||||
|
// chkShowFps
|
||||||
|
//
|
||||||
|
this.chkShowFps.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.chkShowFps.AutoSize = true;
|
||||||
|
this.tlpMain.SetColumnSpan(this.chkShowFps, 2);
|
||||||
|
this.chkShowFps.Location = new System.Drawing.Point(3, 169);
|
||||||
|
this.chkShowFps.Name = "chkShowFps";
|
||||||
|
this.chkShowFps.Size = new System.Drawing.Size(76, 17);
|
||||||
|
this.chkShowFps.TabIndex = 9;
|
||||||
|
this.chkShowFps.Text = "Show FPS";
|
||||||
|
this.chkShowFps.UseVisualStyleBackColor = true;
|
||||||
|
this.chkShowFps.Visible = false;
|
||||||
|
//
|
||||||
|
// chkIntegerFpsMode
|
||||||
|
//
|
||||||
|
this.chkIntegerFpsMode.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.chkIntegerFpsMode.AutoSize = true;
|
||||||
|
this.tlpMain.SetColumnSpan(this.chkIntegerFpsMode, 2);
|
||||||
|
this.chkIntegerFpsMode.Location = new System.Drawing.Point(3, 50);
|
||||||
|
this.chkIntegerFpsMode.Name = "chkIntegerFpsMode";
|
||||||
|
this.chkIntegerFpsMode.Size = new System.Drawing.Size(308, 17);
|
||||||
|
this.chkIntegerFpsMode.TabIndex = 24;
|
||||||
|
this.chkIntegerFpsMode.Text = "Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)";
|
||||||
|
this.chkIntegerFpsMode.UseVisualStyleBackColor = true;
|
||||||
|
this.chkIntegerFpsMode.Visible = false;
|
||||||
|
//
|
||||||
|
// flpRefreshRate
|
||||||
|
//
|
||||||
|
this.tlpMain.SetColumnSpan(this.flpRefreshRate, 2);
|
||||||
|
this.flpRefreshRate.Controls.Add(this.lblRequestedRefreshRate);
|
||||||
|
this.flpRefreshRate.Controls.Add(this.cboRefreshRate);
|
||||||
|
this.flpRefreshRate.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.flpRefreshRate.Location = new System.Drawing.Point(30, 116);
|
||||||
|
this.flpRefreshRate.Margin = new System.Windows.Forms.Padding(30, 0, 0, 0);
|
||||||
|
this.flpRefreshRate.Name = "flpRefreshRate";
|
||||||
|
this.flpRefreshRate.Size = new System.Drawing.Size(530, 27);
|
||||||
|
this.flpRefreshRate.TabIndex = 26;
|
||||||
|
this.flpRefreshRate.Visible = false;
|
||||||
|
//
|
||||||
|
// lblRequestedRefreshRate
|
||||||
|
//
|
||||||
|
this.lblRequestedRefreshRate.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||||
|
this.lblRequestedRefreshRate.AutoSize = true;
|
||||||
|
this.lblRequestedRefreshRate.Location = new System.Drawing.Point(3, 7);
|
||||||
|
this.lblRequestedRefreshRate.Name = "lblRequestedRefreshRate";
|
||||||
|
this.lblRequestedRefreshRate.Size = new System.Drawing.Size(128, 13);
|
||||||
|
this.lblRequestedRefreshRate.TabIndex = 17;
|
||||||
|
this.lblRequestedRefreshRate.Text = "Requested Refresh Rate:";
|
||||||
|
//
|
||||||
|
// cboRefreshRate
|
||||||
|
//
|
||||||
|
this.cboRefreshRate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cboRefreshRate.FormattingEnabled = true;
|
||||||
|
this.cboRefreshRate.Items.AddRange(new object[] {
|
||||||
|
"Auto",
|
||||||
|
"NTSC (8:7)",
|
||||||
|
"PAL (18:13)",
|
||||||
|
"Standard (4:3)",
|
||||||
|
"Widescreen (16:9)"});
|
||||||
|
this.cboRefreshRate.Location = new System.Drawing.Point(137, 3);
|
||||||
|
this.cboRefreshRate.Name = "cboRefreshRate";
|
||||||
|
this.cboRefreshRate.Size = new System.Drawing.Size(68, 21);
|
||||||
|
this.cboRefreshRate.TabIndex = 25;
|
||||||
|
//
|
||||||
|
// tpgPicture
|
||||||
|
//
|
||||||
|
this.tpgPicture.Controls.Add(this.tableLayoutPanel5);
|
||||||
|
this.tpgPicture.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tpgPicture.Name = "tpgPicture";
|
||||||
|
this.tpgPicture.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tpgPicture.Size = new System.Drawing.Size(566, 382);
|
||||||
|
this.tpgPicture.TabIndex = 4;
|
||||||
|
this.tpgPicture.Text = "Picture";
|
||||||
|
this.tpgPicture.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tableLayoutPanel5
|
||||||
|
//
|
||||||
|
this.tableLayoutPanel5.ColumnCount = 2;
|
||||||
|
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||||
|
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||||
|
this.tableLayoutPanel5.Controls.Add(this.tableLayoutPanel7, 0, 3);
|
||||||
|
this.tableLayoutPanel5.Controls.Add(this.grpNtscFilter, 1, 1);
|
||||||
|
this.tableLayoutPanel5.Controls.Add(this.grpCommon, 0, 1);
|
||||||
|
this.tableLayoutPanel5.Controls.Add(this.grpScanlines, 0, 2);
|
||||||
|
this.tableLayoutPanel5.Controls.Add(this.tableLayoutPanel8, 0, 0);
|
||||||
|
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 3);
|
||||||
|
this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
|
||||||
|
this.tableLayoutPanel5.RowCount = 4;
|
||||||
|
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tableLayoutPanel5.Size = new System.Drawing.Size(560, 376);
|
||||||
|
this.tableLayoutPanel5.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// tableLayoutPanel7
|
||||||
|
//
|
||||||
|
this.tableLayoutPanel7.ColumnCount = 2;
|
||||||
|
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 36.92308F));
|
||||||
|
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 63.07692F));
|
||||||
|
this.tableLayoutPanel7.Controls.Add(this.btnSelectPreset, 1, 0);
|
||||||
|
this.tableLayoutPanel7.Controls.Add(this.btnResetPictureSettings, 0, 0);
|
||||||
|
this.tableLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tableLayoutPanel7.Location = new System.Drawing.Point(0, 341);
|
||||||
|
this.tableLayoutPanel7.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.tableLayoutPanel7.Name = "tableLayoutPanel7";
|
||||||
|
this.tableLayoutPanel7.RowCount = 1;
|
||||||
|
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||||
|
this.tableLayoutPanel7.Size = new System.Drawing.Size(280, 35);
|
||||||
|
this.tableLayoutPanel7.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// btnSelectPreset
|
||||||
|
//
|
||||||
|
this.btnSelectPreset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.btnSelectPreset.AutoSize = true;
|
||||||
|
this.btnSelectPreset.Image = global::Mesen.GUI.Properties.Resources.DownArrow;
|
||||||
|
this.btnSelectPreset.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||||
|
this.btnSelectPreset.Location = new System.Drawing.Point(178, 9);
|
||||||
|
this.btnSelectPreset.Name = "btnSelectPreset";
|
||||||
|
this.btnSelectPreset.Padding = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||||
|
this.btnSelectPreset.Size = new System.Drawing.Size(99, 23);
|
||||||
|
this.btnSelectPreset.TabIndex = 3;
|
||||||
|
this.btnSelectPreset.Text = "Select Preset...";
|
||||||
|
this.btnSelectPreset.TextImageRelation = System.Windows.Forms.TextImageRelation.TextBeforeImage;
|
||||||
|
this.btnSelectPreset.UseVisualStyleBackColor = true;
|
||||||
|
this.btnSelectPreset.Click += new System.EventHandler(this.btnSelectPreset_Click);
|
||||||
|
//
|
||||||
|
// btnResetPictureSettings
|
||||||
|
//
|
||||||
|
this.btnResetPictureSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
|
this.btnResetPictureSettings.AutoSize = true;
|
||||||
|
this.btnResetPictureSettings.Location = new System.Drawing.Point(3, 9);
|
||||||
|
this.btnResetPictureSettings.Name = "btnResetPictureSettings";
|
||||||
|
this.btnResetPictureSettings.Size = new System.Drawing.Size(45, 23);
|
||||||
|
this.btnResetPictureSettings.TabIndex = 3;
|
||||||
|
this.btnResetPictureSettings.Text = "Reset";
|
||||||
|
this.btnResetPictureSettings.UseVisualStyleBackColor = true;
|
||||||
|
this.btnResetPictureSettings.Click += new System.EventHandler(this.btnResetPictureSettings_Click);
|
||||||
|
//
|
||||||
|
// grpNtscFilter
|
||||||
|
//
|
||||||
|
this.grpNtscFilter.Controls.Add(this.tlpNtscFilter);
|
||||||
|
this.grpNtscFilter.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.grpNtscFilter.Location = new System.Drawing.Point(282, 27);
|
||||||
|
this.grpNtscFilter.Margin = new System.Windows.Forms.Padding(2, 0, 0, 0);
|
||||||
|
this.grpNtscFilter.Name = "grpNtscFilter";
|
||||||
|
this.tableLayoutPanel5.SetRowSpan(this.grpNtscFilter, 3);
|
||||||
|
this.grpNtscFilter.Size = new System.Drawing.Size(278, 349);
|
||||||
|
this.grpNtscFilter.TabIndex = 4;
|
||||||
|
this.grpNtscFilter.TabStop = false;
|
||||||
|
this.grpNtscFilter.Text = "NTSC Filter";
|
||||||
|
//
|
||||||
|
// tlpNtscFilter
|
||||||
|
//
|
||||||
|
this.tlpNtscFilter.ColumnCount = 1;
|
||||||
|
this.tlpNtscFilter.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tlpNtscFilter.Controls.Add(this.chkMergeFields, 0, 6);
|
||||||
|
this.tlpNtscFilter.Controls.Add(this.trkArtifacts, 0, 0);
|
||||||
|
this.tlpNtscFilter.Controls.Add(this.trkBleed, 0, 1);
|
||||||
|
this.tlpNtscFilter.Controls.Add(this.trkFringing, 0, 2);
|
||||||
|
this.tlpNtscFilter.Controls.Add(this.trkGamma, 0, 3);
|
||||||
|
this.tlpNtscFilter.Controls.Add(this.trkResolution, 0, 4);
|
||||||
|
this.tlpNtscFilter.Controls.Add(this.trkSharpness, 0, 5);
|
||||||
|
this.tlpNtscFilter.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tlpNtscFilter.Location = new System.Drawing.Point(3, 16);
|
||||||
|
this.tlpNtscFilter.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.tlpNtscFilter.Name = "tlpNtscFilter";
|
||||||
|
this.tlpNtscFilter.RowCount = 7;
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tlpNtscFilter.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||||
|
this.tlpNtscFilter.Size = new System.Drawing.Size(272, 330);
|
||||||
|
this.tlpNtscFilter.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// chkMergeFields
|
||||||
|
//
|
||||||
|
this.chkMergeFields.AutoSize = true;
|
||||||
|
this.chkMergeFields.Location = new System.Drawing.Point(3, 303);
|
||||||
|
this.chkMergeFields.Name = "chkMergeFields";
|
||||||
|
this.chkMergeFields.Size = new System.Drawing.Size(86, 17);
|
||||||
|
this.chkMergeFields.TabIndex = 30;
|
||||||
|
this.chkMergeFields.Text = "Merge Fields";
|
||||||
|
this.chkMergeFields.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// trkArtifacts
|
||||||
|
//
|
||||||
|
this.trkArtifacts.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkArtifacts.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.trkArtifacts.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkArtifacts.Maximum = 100;
|
||||||
|
this.trkArtifacts.MaximumSize = new System.Drawing.Size(0, 60);
|
||||||
|
this.trkArtifacts.Minimum = -100;
|
||||||
|
this.trkArtifacts.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkArtifacts.Name = "trkArtifacts";
|
||||||
|
this.trkArtifacts.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkArtifacts.TabIndex = 24;
|
||||||
|
this.trkArtifacts.Text = "Artifacts";
|
||||||
|
this.trkArtifacts.Value = 0;
|
||||||
|
//
|
||||||
|
// trkBleed
|
||||||
|
//
|
||||||
|
this.trkBleed.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkBleed.Location = new System.Drawing.Point(0, 50);
|
||||||
|
this.trkBleed.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkBleed.Maximum = 100;
|
||||||
|
this.trkBleed.MaximumSize = new System.Drawing.Size(400, 55);
|
||||||
|
this.trkBleed.Minimum = -100;
|
||||||
|
this.trkBleed.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkBleed.Name = "trkBleed";
|
||||||
|
this.trkBleed.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkBleed.TabIndex = 25;
|
||||||
|
this.trkBleed.Text = "Bleed";
|
||||||
|
this.trkBleed.Value = 0;
|
||||||
|
//
|
||||||
|
// trkFringing
|
||||||
|
//
|
||||||
|
this.trkFringing.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkFringing.Location = new System.Drawing.Point(0, 100);
|
||||||
|
this.trkFringing.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkFringing.Maximum = 100;
|
||||||
|
this.trkFringing.MaximumSize = new System.Drawing.Size(0, 41);
|
||||||
|
this.trkFringing.Minimum = -100;
|
||||||
|
this.trkFringing.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkFringing.Name = "trkFringing";
|
||||||
|
this.trkFringing.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkFringing.TabIndex = 26;
|
||||||
|
this.trkFringing.Text = "Fringing";
|
||||||
|
this.trkFringing.Value = 0;
|
||||||
|
//
|
||||||
|
// trkGamma
|
||||||
|
//
|
||||||
|
this.trkGamma.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkGamma.Location = new System.Drawing.Point(0, 150);
|
||||||
|
this.trkGamma.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkGamma.Maximum = 100;
|
||||||
|
this.trkGamma.MaximumSize = new System.Drawing.Size(0, 41);
|
||||||
|
this.trkGamma.Minimum = -100;
|
||||||
|
this.trkGamma.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkGamma.Name = "trkGamma";
|
||||||
|
this.trkGamma.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkGamma.TabIndex = 27;
|
||||||
|
this.trkGamma.Text = "Gamma";
|
||||||
|
this.trkGamma.Value = 0;
|
||||||
|
//
|
||||||
|
// trkResolution
|
||||||
|
//
|
||||||
|
this.trkResolution.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkResolution.Location = new System.Drawing.Point(0, 200);
|
||||||
|
this.trkResolution.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkResolution.Maximum = 100;
|
||||||
|
this.trkResolution.MaximumSize = new System.Drawing.Size(0, 41);
|
||||||
|
this.trkResolution.Minimum = -100;
|
||||||
|
this.trkResolution.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkResolution.Name = "trkResolution";
|
||||||
|
this.trkResolution.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkResolution.TabIndex = 28;
|
||||||
|
this.trkResolution.Text = "Resolution";
|
||||||
|
this.trkResolution.Value = 0;
|
||||||
|
//
|
||||||
|
// trkSharpness
|
||||||
|
//
|
||||||
|
this.trkSharpness.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkSharpness.Location = new System.Drawing.Point(0, 250);
|
||||||
|
this.trkSharpness.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkSharpness.Maximum = 100;
|
||||||
|
this.trkSharpness.MaximumSize = new System.Drawing.Size(0, 41);
|
||||||
|
this.trkSharpness.Minimum = -100;
|
||||||
|
this.trkSharpness.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkSharpness.Name = "trkSharpness";
|
||||||
|
this.trkSharpness.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkSharpness.TabIndex = 29;
|
||||||
|
this.trkSharpness.Text = "Sharpness";
|
||||||
|
this.trkSharpness.Value = 0;
|
||||||
|
//
|
||||||
|
// grpCommon
|
||||||
|
//
|
||||||
|
this.grpCommon.Controls.Add(this.tableLayoutPanel4);
|
||||||
|
this.grpCommon.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.grpCommon.Location = new System.Drawing.Point(0, 27);
|
||||||
|
this.grpCommon.Margin = new System.Windows.Forms.Padding(0, 0, 2, 0);
|
||||||
|
this.grpCommon.Name = "grpCommon";
|
||||||
|
this.grpCommon.Padding = new System.Windows.Forms.Padding(3, 2, 3, 2);
|
||||||
|
this.grpCommon.Size = new System.Drawing.Size(278, 242);
|
||||||
|
this.grpCommon.TabIndex = 3;
|
||||||
|
this.grpCommon.TabStop = false;
|
||||||
|
this.grpCommon.Text = "Common Settings";
|
||||||
|
//
|
||||||
|
// tableLayoutPanel4
|
||||||
|
//
|
||||||
|
this.tableLayoutPanel4.ColumnCount = 1;
|
||||||
|
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||||
|
this.tableLayoutPanel4.Controls.Add(this.chkBilinearInterpolation, 0, 4);
|
||||||
|
this.tableLayoutPanel4.Controls.Add(this.trkBrightness, 0, 0);
|
||||||
|
this.tableLayoutPanel4.Controls.Add(this.trkContrast, 0, 1);
|
||||||
|
this.tableLayoutPanel4.Controls.Add(this.trkHue, 0, 2);
|
||||||
|
this.tableLayoutPanel4.Controls.Add(this.trkSaturation, 0, 3);
|
||||||
|
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tableLayoutPanel4.Location = new System.Drawing.Point(3, 15);
|
||||||
|
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
|
||||||
|
this.tableLayoutPanel4.RowCount = 5;
|
||||||
|
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||||
|
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tableLayoutPanel4.Size = new System.Drawing.Size(272, 225);
|
||||||
|
this.tableLayoutPanel4.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// chkBilinearInterpolation
|
||||||
|
//
|
||||||
|
this.chkBilinearInterpolation.AutoSize = true;
|
||||||
|
this.tableLayoutPanel4.SetColumnSpan(this.chkBilinearInterpolation, 2);
|
||||||
|
this.chkBilinearInterpolation.Location = new System.Drawing.Point(3, 203);
|
||||||
|
this.chkBilinearInterpolation.Name = "chkBilinearInterpolation";
|
||||||
|
this.chkBilinearInterpolation.Size = new System.Drawing.Size(206, 17);
|
||||||
|
this.chkBilinearInterpolation.TabIndex = 28;
|
||||||
|
this.chkBilinearInterpolation.Text = "Use bilinear interpolation when scaling";
|
||||||
|
this.chkBilinearInterpolation.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// trkBrightness
|
||||||
|
//
|
||||||
|
this.trkBrightness.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkBrightness.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.trkBrightness.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkBrightness.Maximum = 100;
|
||||||
|
this.trkBrightness.MaximumSize = new System.Drawing.Size(0, 60);
|
||||||
|
this.trkBrightness.Minimum = -100;
|
||||||
|
this.trkBrightness.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkBrightness.Name = "trkBrightness";
|
||||||
|
this.trkBrightness.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkBrightness.TabIndex = 24;
|
||||||
|
this.trkBrightness.Text = "Brightness";
|
||||||
|
this.trkBrightness.Value = 0;
|
||||||
|
//
|
||||||
|
// trkContrast
|
||||||
|
//
|
||||||
|
this.trkContrast.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkContrast.Location = new System.Drawing.Point(0, 50);
|
||||||
|
this.trkContrast.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkContrast.Maximum = 100;
|
||||||
|
this.trkContrast.MaximumSize = new System.Drawing.Size(400, 55);
|
||||||
|
this.trkContrast.Minimum = -100;
|
||||||
|
this.trkContrast.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkContrast.Name = "trkContrast";
|
||||||
|
this.trkContrast.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkContrast.TabIndex = 25;
|
||||||
|
this.trkContrast.Text = "Contrast";
|
||||||
|
this.trkContrast.Value = 0;
|
||||||
|
//
|
||||||
|
// trkHue
|
||||||
|
//
|
||||||
|
this.trkHue.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkHue.Location = new System.Drawing.Point(0, 100);
|
||||||
|
this.trkHue.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkHue.Maximum = 100;
|
||||||
|
this.trkHue.MaximumSize = new System.Drawing.Size(0, 41);
|
||||||
|
this.trkHue.Minimum = -100;
|
||||||
|
this.trkHue.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkHue.Name = "trkHue";
|
||||||
|
this.trkHue.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkHue.TabIndex = 26;
|
||||||
|
this.trkHue.Text = "Hue";
|
||||||
|
this.trkHue.Value = 0;
|
||||||
|
//
|
||||||
|
// trkSaturation
|
||||||
|
//
|
||||||
|
this.trkSaturation.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkSaturation.Location = new System.Drawing.Point(0, 150);
|
||||||
|
this.trkSaturation.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkSaturation.Maximum = 100;
|
||||||
|
this.trkSaturation.MaximumSize = new System.Drawing.Size(0, 41);
|
||||||
|
this.trkSaturation.Minimum = -100;
|
||||||
|
this.trkSaturation.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkSaturation.Name = "trkSaturation";
|
||||||
|
this.trkSaturation.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkSaturation.TabIndex = 27;
|
||||||
|
this.trkSaturation.Text = "Saturation";
|
||||||
|
this.trkSaturation.Value = 0;
|
||||||
|
//
|
||||||
|
// grpScanlines
|
||||||
|
//
|
||||||
|
this.grpScanlines.Controls.Add(this.trkScanlines);
|
||||||
|
this.grpScanlines.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.grpScanlines.Location = new System.Drawing.Point(0, 269);
|
||||||
|
this.grpScanlines.Margin = new System.Windows.Forms.Padding(0, 0, 2, 0);
|
||||||
|
this.grpScanlines.Name = "grpScanlines";
|
||||||
|
this.grpScanlines.Size = new System.Drawing.Size(278, 72);
|
||||||
|
this.grpScanlines.TabIndex = 5;
|
||||||
|
this.grpScanlines.TabStop = false;
|
||||||
|
this.grpScanlines.Text = "Scanlines";
|
||||||
|
//
|
||||||
|
// trkScanlines
|
||||||
|
//
|
||||||
|
this.trkScanlines.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.trkScanlines.Location = new System.Drawing.Point(3, 16);
|
||||||
|
this.trkScanlines.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.trkScanlines.Maximum = 100;
|
||||||
|
this.trkScanlines.MaximumSize = new System.Drawing.Size(0, 41);
|
||||||
|
this.trkScanlines.Minimum = 0;
|
||||||
|
this.trkScanlines.MinimumSize = new System.Drawing.Size(206, 50);
|
||||||
|
this.trkScanlines.Name = "trkScanlines";
|
||||||
|
this.trkScanlines.Size = new System.Drawing.Size(272, 50);
|
||||||
|
this.trkScanlines.TabIndex = 28;
|
||||||
|
this.trkScanlines.Text = "Scanlines";
|
||||||
|
this.trkScanlines.Value = 0;
|
||||||
|
//
|
||||||
|
// tableLayoutPanel8
|
||||||
|
//
|
||||||
|
this.tableLayoutPanel8.ColumnCount = 2;
|
||||||
|
this.tableLayoutPanel5.SetColumnSpan(this.tableLayoutPanel8, 2);
|
||||||
|
this.tableLayoutPanel8.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||||
|
this.tableLayoutPanel8.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tableLayoutPanel8.Controls.Add(this.cboFilter, 1, 0);
|
||||||
|
this.tableLayoutPanel8.Controls.Add(this.lblVideoFilter, 0, 0);
|
||||||
|
this.tableLayoutPanel8.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.tableLayoutPanel8.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.tableLayoutPanel8.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.tableLayoutPanel8.Name = "tableLayoutPanel8";
|
||||||
|
this.tableLayoutPanel8.RowCount = 1;
|
||||||
|
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
|
||||||
|
this.tableLayoutPanel8.Size = new System.Drawing.Size(560, 27);
|
||||||
|
this.tableLayoutPanel8.TabIndex = 6;
|
||||||
|
//
|
||||||
|
// cboFilter
|
||||||
|
//
|
||||||
|
this.cboFilter.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.cboFilter.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cboFilter.FormattingEnabled = true;
|
||||||
|
this.cboFilter.Items.AddRange(new object[] {
|
||||||
|
"None",
|
||||||
|
"NTSC"});
|
||||||
|
this.cboFilter.Location = new System.Drawing.Point(41, 3);
|
||||||
|
this.cboFilter.Name = "cboFilter";
|
||||||
|
this.cboFilter.Size = new System.Drawing.Size(516, 21);
|
||||||
|
this.cboFilter.TabIndex = 15;
|
||||||
|
//
|
||||||
|
// lblVideoFilter
|
||||||
|
//
|
||||||
|
this.lblVideoFilter.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||||
|
this.lblVideoFilter.AutoSize = true;
|
||||||
|
this.lblVideoFilter.Location = new System.Drawing.Point(3, 7);
|
||||||
|
this.lblVideoFilter.Name = "lblVideoFilter";
|
||||||
|
this.lblVideoFilter.Size = new System.Drawing.Size(32, 13);
|
||||||
|
this.lblVideoFilter.TabIndex = 13;
|
||||||
|
this.lblVideoFilter.Text = "Filter:";
|
||||||
|
//
|
||||||
|
// ctxPicturePresets
|
||||||
|
//
|
||||||
|
this.ctxPicturePresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.mnuPresetComposite,
|
||||||
|
this.mnuPresetSVideo,
|
||||||
|
this.mnuPresetRgb,
|
||||||
|
this.mnuPresetMonochrome});
|
||||||
|
this.ctxPicturePresets.Name = "contextPicturePresets";
|
||||||
|
this.ctxPicturePresets.Size = new System.Drawing.Size(148, 92);
|
||||||
|
//
|
||||||
|
// mnuPresetComposite
|
||||||
|
//
|
||||||
|
this.mnuPresetComposite.Name = "mnuPresetComposite";
|
||||||
|
this.mnuPresetComposite.Size = new System.Drawing.Size(147, 22);
|
||||||
|
this.mnuPresetComposite.Text = "Composite";
|
||||||
|
this.mnuPresetComposite.Click += new System.EventHandler(this.mnuPresetComposite_Click);
|
||||||
|
//
|
||||||
|
// mnuPresetSVideo
|
||||||
|
//
|
||||||
|
this.mnuPresetSVideo.Name = "mnuPresetSVideo";
|
||||||
|
this.mnuPresetSVideo.Size = new System.Drawing.Size(147, 22);
|
||||||
|
this.mnuPresetSVideo.Text = "S-Video";
|
||||||
|
this.mnuPresetSVideo.Click += new System.EventHandler(this.mnuPresetSVideo_Click);
|
||||||
|
//
|
||||||
|
// mnuPresetRgb
|
||||||
|
//
|
||||||
|
this.mnuPresetRgb.Name = "mnuPresetRgb";
|
||||||
|
this.mnuPresetRgb.Size = new System.Drawing.Size(147, 22);
|
||||||
|
this.mnuPresetRgb.Text = "RGB";
|
||||||
|
this.mnuPresetRgb.Click += new System.EventHandler(this.mnuPresetRgb_Click);
|
||||||
|
//
|
||||||
|
// mnuPresetMonochrome
|
||||||
|
//
|
||||||
|
this.mnuPresetMonochrome.Name = "mnuPresetMonochrome";
|
||||||
|
this.mnuPresetMonochrome.Size = new System.Drawing.Size(147, 22);
|
||||||
|
this.mnuPresetMonochrome.Text = "Monochrome";
|
||||||
|
this.mnuPresetMonochrome.Click += new System.EventHandler(this.mnuPresetMonochrome_Click);
|
||||||
|
//
|
||||||
|
// frmVideoConfig
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(574, 437);
|
||||||
|
this.Controls.Add(this.tabMain);
|
||||||
|
this.Name = "frmVideoConfig";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
|
this.Text = "frmVideoConfig";
|
||||||
|
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
|
||||||
|
this.Controls.SetChildIndex(this.tabMain, 0);
|
||||||
|
this.tabMain.ResumeLayout(false);
|
||||||
|
this.tpgGeneral.ResumeLayout(false);
|
||||||
|
this.tlpMain.ResumeLayout(false);
|
||||||
|
this.tlpMain.PerformLayout();
|
||||||
|
this.flowLayoutPanel6.ResumeLayout(false);
|
||||||
|
this.flowLayoutPanel6.PerformLayout();
|
||||||
|
this.flpRefreshRate.ResumeLayout(false);
|
||||||
|
this.flpRefreshRate.PerformLayout();
|
||||||
|
this.tpgPicture.ResumeLayout(false);
|
||||||
|
this.tableLayoutPanel5.ResumeLayout(false);
|
||||||
|
this.tableLayoutPanel7.ResumeLayout(false);
|
||||||
|
this.tableLayoutPanel7.PerformLayout();
|
||||||
|
this.grpNtscFilter.ResumeLayout(false);
|
||||||
|
this.tlpNtscFilter.ResumeLayout(false);
|
||||||
|
this.tlpNtscFilter.PerformLayout();
|
||||||
|
this.grpCommon.ResumeLayout(false);
|
||||||
|
this.tableLayoutPanel4.ResumeLayout(false);
|
||||||
|
this.tableLayoutPanel4.PerformLayout();
|
||||||
|
this.grpScanlines.ResumeLayout(false);
|
||||||
|
this.tableLayoutPanel8.ResumeLayout(false);
|
||||||
|
this.tableLayoutPanel8.PerformLayout();
|
||||||
|
this.ctxPicturePresets.ResumeLayout(false);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.TabControl tabMain;
|
||||||
|
private System.Windows.Forms.TabPage tpgGeneral;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tlpMain;
|
||||||
|
private System.Windows.Forms.CheckBox chkUseExclusiveFullscreen;
|
||||||
|
private System.Windows.Forms.Label lblVideoScale;
|
||||||
|
private System.Windows.Forms.CheckBox chkVerticalSync;
|
||||||
|
private System.Windows.Forms.Label lblDisplayRatio;
|
||||||
|
private Controls.MesenNumericUpDown nudScale;
|
||||||
|
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel6;
|
||||||
|
private System.Windows.Forms.ComboBox cboAspectRatio;
|
||||||
|
private System.Windows.Forms.Label lblCustomRatio;
|
||||||
|
private Controls.MesenNumericUpDown nudCustomRatio;
|
||||||
|
private System.Windows.Forms.CheckBox chkFullscreenForceIntegerScale;
|
||||||
|
private System.Windows.Forms.CheckBox chkShowFps;
|
||||||
|
private System.Windows.Forms.CheckBox chkIntegerFpsMode;
|
||||||
|
private System.Windows.Forms.FlowLayoutPanel flpRefreshRate;
|
||||||
|
private System.Windows.Forms.Label lblRequestedRefreshRate;
|
||||||
|
private System.Windows.Forms.ComboBox cboRefreshRate;
|
||||||
|
private System.Windows.Forms.TabPage tpgPicture;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7;
|
||||||
|
private System.Windows.Forms.Button btnSelectPreset;
|
||||||
|
private System.Windows.Forms.Button btnResetPictureSettings;
|
||||||
|
private System.Windows.Forms.GroupBox grpNtscFilter;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tlpNtscFilter;
|
||||||
|
private System.Windows.Forms.CheckBox chkMergeFields;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkArtifacts;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkBleed;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkFringing;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkGamma;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkResolution;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkSharpness;
|
||||||
|
private System.Windows.Forms.GroupBox grpCommon;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
|
||||||
|
private System.Windows.Forms.CheckBox chkBilinearInterpolation;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkBrightness;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkContrast;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkHue;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkSaturation;
|
||||||
|
private System.Windows.Forms.GroupBox grpScanlines;
|
||||||
|
private Controls.ctrlHorizontalTrackbar trkScanlines;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel8;
|
||||||
|
private System.Windows.Forms.ComboBox cboFilter;
|
||||||
|
private System.Windows.Forms.Label lblVideoFilter;
|
||||||
|
private System.Windows.Forms.ContextMenuStrip ctxPicturePresets;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuPresetComposite;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuPresetSVideo;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuPresetRgb;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuPresetMonochrome;
|
||||||
|
}
|
||||||
|
}
|
128
UI/Forms/Config/frmVideoConfig.cs
Normal file
128
UI/Forms/Config/frmVideoConfig.cs
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
using Mesen.GUI.Config;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Mesen.GUI.Forms.Config
|
||||||
|
{
|
||||||
|
public partial class frmVideoConfig : BaseConfigForm
|
||||||
|
{
|
||||||
|
public frmVideoConfig()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
if(DesignMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity = ConfigManager.Config.Video.Clone();
|
||||||
|
|
||||||
|
//AddBinding(nameof(VideoConfig.ShowFPS), chkShowFps);
|
||||||
|
AddBinding(nameof(VideoConfig.UseBilinearInterpolation), chkBilinearInterpolation);
|
||||||
|
AddBinding(nameof(VideoConfig.VerticalSync), chkVerticalSync);
|
||||||
|
AddBinding(nameof(VideoConfig.IntegerFpsMode), chkIntegerFpsMode);
|
||||||
|
AddBinding(nameof(VideoConfig.FullscreenForceIntegerScale), chkFullscreenForceIntegerScale);
|
||||||
|
AddBinding(nameof(VideoConfig.UseExclusiveFullscreen), chkUseExclusiveFullscreen);
|
||||||
|
AddBinding(nameof(VideoConfig.ExclusiveFullscreenRefreshRate), cboRefreshRate);
|
||||||
|
|
||||||
|
AddBinding(nameof(VideoConfig.VideoScale), nudScale);
|
||||||
|
AddBinding(nameof(VideoConfig.AspectRatio), cboAspectRatio);
|
||||||
|
AddBinding(nameof(VideoConfig.CustomAspectRatio), nudCustomRatio);
|
||||||
|
AddBinding(nameof(VideoConfig.VideoFilter), cboFilter);
|
||||||
|
|
||||||
|
AddBinding(nameof(VideoConfig.Brightness), trkBrightness);
|
||||||
|
AddBinding(nameof(VideoConfig.Contrast), trkContrast);
|
||||||
|
AddBinding(nameof(VideoConfig.Hue), trkHue);
|
||||||
|
AddBinding(nameof(VideoConfig.Saturation), trkSaturation);
|
||||||
|
AddBinding(nameof(VideoConfig.ScanlineIntensity), trkScanlines);
|
||||||
|
|
||||||
|
AddBinding(nameof(VideoConfig.NtscArtifacts), trkArtifacts);
|
||||||
|
AddBinding(nameof(VideoConfig.NtscBleed), trkBleed);
|
||||||
|
AddBinding(nameof(VideoConfig.NtscFringing), trkFringing);
|
||||||
|
AddBinding(nameof(VideoConfig.NtscGamma), trkGamma);
|
||||||
|
AddBinding(nameof(VideoConfig.NtscResolution), trkResolution);
|
||||||
|
AddBinding(nameof(VideoConfig.NtscSharpness), trkSharpness);
|
||||||
|
AddBinding(nameof(VideoConfig.NtscMergeFields), chkMergeFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ValidateInput()
|
||||||
|
{
|
||||||
|
UpdateObject();
|
||||||
|
UpdateCustomRatioVisibility();
|
||||||
|
|
||||||
|
VideoFilterType filter = ((VideoConfig)Entity).VideoFilter;
|
||||||
|
grpNtscFilter.Visible = (filter == VideoFilterType.NTSC);
|
||||||
|
|
||||||
|
((VideoConfig)this.Entity).ApplyConfig();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApply()
|
||||||
|
{
|
||||||
|
ConfigManager.Config.Video = (VideoConfig)this.Entity;
|
||||||
|
ConfigManager.ApplyChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCustomRatioVisibility()
|
||||||
|
{
|
||||||
|
VideoAspectRatio ratio = cboAspectRatio.GetEnumValue<VideoAspectRatio>();
|
||||||
|
lblCustomRatio.Visible = ratio == VideoAspectRatio.Custom;
|
||||||
|
nudCustomRatio.Visible = ratio == VideoAspectRatio.Custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnResetPictureSettings_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SetNtscPreset(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false);
|
||||||
|
cboFilter.SetEnumValue(VideoFilterType.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSelectPreset_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ctxPicturePresets.Show(btnSelectPreset.PointToScreen(new Point(0, btnSelectPreset.Height - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetNtscPreset(int hue, int saturation, int contrast, int brightness, int sharpness, int gamma, int resolution, int artifacts, int fringing, int bleed, int scanlines, bool mergeFields)
|
||||||
|
{
|
||||||
|
cboFilter.SetEnumValue(VideoFilterType.NTSC);
|
||||||
|
trkHue.Value = hue;
|
||||||
|
trkSaturation.Value = saturation;
|
||||||
|
trkContrast.Value = contrast;
|
||||||
|
trkBrightness.Value = brightness;
|
||||||
|
trkSharpness.Value = sharpness;
|
||||||
|
trkGamma.Value = gamma;
|
||||||
|
trkResolution.Value = resolution;
|
||||||
|
trkArtifacts.Value = artifacts;
|
||||||
|
trkFringing.Value = fringing;
|
||||||
|
trkBleed.Value = bleed;
|
||||||
|
chkMergeFields.Checked = mergeFields;
|
||||||
|
|
||||||
|
trkScanlines.Value = scanlines;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mnuPresetComposite_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SetNtscPreset(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mnuPresetSVideo_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SetNtscPreset(0, 0, 0, 0, 20, 0, 20, -100, -100, 0, 15, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mnuPresetRgb_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SetNtscPreset(0, 0, 0, 0, 20, 0, 70, -100, -100, -100, 15, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mnuPresetMonochrome_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SetNtscPreset(0, -100, 0, 0, 20, 0, 70, -20, -20, -10, 15, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
126
UI/Forms/Config/frmVideoConfig.resx
Normal file
126
UI/Forms/Config/frmVideoConfig.resx
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="ctxPicturePresets.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>107, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
|
@ -102,7 +102,11 @@ namespace Mesen.GUI.Forms
|
||||||
((ctrlTrackbar)kvp.Value).Value = (int)(uint)value;
|
((ctrlTrackbar)kvp.Value).Value = (int)(uint)value;
|
||||||
}
|
}
|
||||||
} else if(kvp.Value is ctrlHorizontalTrackbar) {
|
} else if(kvp.Value is ctrlHorizontalTrackbar) {
|
||||||
|
if(field.FieldType == typeof(double)) {
|
||||||
|
((ctrlHorizontalTrackbar)kvp.Value).Value = (int)((double)value * 100);
|
||||||
|
} else {
|
||||||
((ctrlHorizontalTrackbar)kvp.Value).Value = (int)value;
|
((ctrlHorizontalTrackbar)kvp.Value).Value = (int)value;
|
||||||
|
}
|
||||||
} else if(kvp.Value is TrackBar) {
|
} else if(kvp.Value is TrackBar) {
|
||||||
if(field.FieldType == typeof(Int32)) {
|
if(field.FieldType == typeof(Int32)) {
|
||||||
((TrackBar)kvp.Value).Value = (int)value;
|
((TrackBar)kvp.Value).Value = (int)value;
|
||||||
|
@ -236,7 +240,11 @@ namespace Mesen.GUI.Forms
|
||||||
field.SetValue(Entity, (UInt32)((ctrlTrackbar)kvp.Value).Value);
|
field.SetValue(Entity, (UInt32)((ctrlTrackbar)kvp.Value).Value);
|
||||||
}
|
}
|
||||||
} else if(kvp.Value is ctrlHorizontalTrackbar) {
|
} else if(kvp.Value is ctrlHorizontalTrackbar) {
|
||||||
|
if(field.FieldType == typeof(double)) {
|
||||||
|
field.SetValue(Entity, ((ctrlHorizontalTrackbar)kvp.Value).Value / 100.0);
|
||||||
|
} else {
|
||||||
field.SetValue(Entity, (Int32)((ctrlHorizontalTrackbar)kvp.Value).Value);
|
field.SetValue(Entity, (Int32)((ctrlHorizontalTrackbar)kvp.Value).Value);
|
||||||
|
}
|
||||||
} else if(kvp.Value is TrackBar) {
|
} else if(kvp.Value is TrackBar) {
|
||||||
if(field.FieldType == typeof(Int32)) {
|
if(field.FieldType == typeof(Int32)) {
|
||||||
field.SetValue(Entity, ((TrackBar)kvp.Value).Value);
|
field.SetValue(Entity, ((TrackBar)kvp.Value).Value);
|
||||||
|
|
41
UI/Forms/frmMain.Designer.cs
generated
41
UI/Forms/frmMain.Designer.cs
generated
|
@ -31,6 +31,8 @@
|
||||||
this.mnuMain = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
|
this.mnuMain = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
|
||||||
this.mnuFile = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuFile = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuOpen = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuOpen = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuVideoConfig = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuRun = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuRun = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuStep = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuStep = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
@ -41,12 +43,14 @@
|
||||||
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuTilemapViewer = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuTilemapViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.pnlRenderer = new System.Windows.Forms.Panel();
|
||||||
this.mnuMain.SuspendLayout();
|
this.mnuMain.SuspendLayout();
|
||||||
|
this.pnlRenderer.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// ctrlRenderer
|
// ctrlRenderer
|
||||||
//
|
//
|
||||||
this.ctrlRenderer.Location = new System.Drawing.Point(0, 27);
|
this.ctrlRenderer.Location = new System.Drawing.Point(0, 0);
|
||||||
this.ctrlRenderer.Name = "ctrlRenderer";
|
this.ctrlRenderer.Name = "ctrlRenderer";
|
||||||
this.ctrlRenderer.Size = new System.Drawing.Size(512, 448);
|
this.ctrlRenderer.Size = new System.Drawing.Size(512, 448);
|
||||||
this.ctrlRenderer.TabIndex = 0;
|
this.ctrlRenderer.TabIndex = 0;
|
||||||
|
@ -55,6 +59,7 @@
|
||||||
//
|
//
|
||||||
this.mnuMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.mnuMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
this.mnuFile,
|
this.mnuFile,
|
||||||
|
this.optionsToolStripMenuItem,
|
||||||
this.debugToolStripMenuItem});
|
this.debugToolStripMenuItem});
|
||||||
this.mnuMain.Location = new System.Drawing.Point(0, 0);
|
this.mnuMain.Location = new System.Drawing.Point(0, 0);
|
||||||
this.mnuMain.Name = "mnuMain";
|
this.mnuMain.Name = "mnuMain";
|
||||||
|
@ -79,6 +84,22 @@
|
||||||
this.mnuOpen.Text = "Open";
|
this.mnuOpen.Text = "Open";
|
||||||
this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
|
this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
|
||||||
//
|
//
|
||||||
|
// optionsToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.mnuVideoConfig});
|
||||||
|
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
||||||
|
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
|
||||||
|
this.optionsToolStripMenuItem.Text = "Options";
|
||||||
|
//
|
||||||
|
// mnuVideoConfig
|
||||||
|
//
|
||||||
|
this.mnuVideoConfig.Image = global::Mesen.GUI.Properties.Resources.VideoOptions;
|
||||||
|
this.mnuVideoConfig.Name = "mnuVideoConfig";
|
||||||
|
this.mnuVideoConfig.Size = new System.Drawing.Size(104, 22);
|
||||||
|
this.mnuVideoConfig.Text = "Video";
|
||||||
|
this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click);
|
||||||
|
//
|
||||||
// debugToolStripMenuItem
|
// debugToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.debugToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.debugToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
@ -164,19 +185,30 @@
|
||||||
this.mnuEventViewer.Text = "Event Viewer";
|
this.mnuEventViewer.Text = "Event Viewer";
|
||||||
this.mnuEventViewer.Click += new System.EventHandler(this.mnuEventViewer_Click);
|
this.mnuEventViewer.Click += new System.EventHandler(this.mnuEventViewer_Click);
|
||||||
//
|
//
|
||||||
|
// pnlRenderer
|
||||||
|
//
|
||||||
|
this.pnlRenderer.BackColor = System.Drawing.Color.Black;
|
||||||
|
this.pnlRenderer.Controls.Add(this.ctrlRenderer);
|
||||||
|
this.pnlRenderer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.pnlRenderer.Location = new System.Drawing.Point(0, 24);
|
||||||
|
this.pnlRenderer.Name = "pnlRenderer";
|
||||||
|
this.pnlRenderer.Size = new System.Drawing.Size(512, 448);
|
||||||
|
this.pnlRenderer.TabIndex = 2;
|
||||||
|
//
|
||||||
// frmMain
|
// frmMain
|
||||||
//
|
//
|
||||||
this.AllowDrop = true;
|
this.AllowDrop = true;
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(512, 475);
|
this.ClientSize = new System.Drawing.Size(512, 472);
|
||||||
this.Controls.Add(this.ctrlRenderer);
|
this.Controls.Add(this.pnlRenderer);
|
||||||
this.Controls.Add(this.mnuMain);
|
this.Controls.Add(this.mnuMain);
|
||||||
this.MainMenuStrip = this.mnuMain;
|
this.MainMenuStrip = this.mnuMain;
|
||||||
this.Name = "frmMain";
|
this.Name = "frmMain";
|
||||||
this.Text = "frmMain";
|
this.Text = "frmMain";
|
||||||
this.mnuMain.ResumeLayout(false);
|
this.mnuMain.ResumeLayout(false);
|
||||||
this.mnuMain.PerformLayout();
|
this.mnuMain.PerformLayout();
|
||||||
|
this.pnlRenderer.ResumeLayout(false);
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
|
@ -198,5 +230,8 @@
|
||||||
private System.Windows.Forms.ToolStripMenuItem mnuMemoryTools;
|
private System.Windows.Forms.ToolStripMenuItem mnuMemoryTools;
|
||||||
private System.Windows.Forms.ToolStripMenuItem mnuTilemapViewer;
|
private System.Windows.Forms.ToolStripMenuItem mnuTilemapViewer;
|
||||||
private System.Windows.Forms.ToolStripMenuItem mnuEventViewer;
|
private System.Windows.Forms.ToolStripMenuItem mnuEventViewer;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuVideoConfig;
|
||||||
|
private System.Windows.Forms.Panel pnlRenderer;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using Mesen.GUI.Config;
|
using Mesen.GUI.Config;
|
||||||
using Mesen.GUI.Debugger;
|
using Mesen.GUI.Debugger;
|
||||||
|
using Mesen.GUI.Forms.Config;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
@ -30,6 +31,8 @@ namespace Mesen.GUI.Forms
|
||||||
EmuApi.InitDll();
|
EmuApi.InitDll();
|
||||||
EmuApi.InitializeEmu(ConfigManager.HomeFolder, Handle, ctrlRenderer.Handle, false, false, false);
|
EmuApi.InitializeEmu(ConfigManager.HomeFolder, Handle, ctrlRenderer.Handle, false, false, false);
|
||||||
|
|
||||||
|
ConfigManager.Config.ApplyConfig();
|
||||||
|
|
||||||
_notifListener = new NotificationListener();
|
_notifListener = new NotificationListener();
|
||||||
_notifListener.OnNotification += OnNotificationReceived;
|
_notifListener.OnNotification += OnNotificationReceived;
|
||||||
|
|
||||||
|
@ -45,6 +48,8 @@ namespace Mesen.GUI.Forms
|
||||||
_notifListener = null;
|
_notifListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigManager.ApplyChanges();
|
||||||
|
|
||||||
DebugApi.ResumeExecution();
|
DebugApi.ResumeExecution();
|
||||||
EmuApi.Stop();
|
EmuApi.Stop();
|
||||||
EmuApi.Release();
|
EmuApi.Release();
|
||||||
|
@ -53,11 +58,41 @@ namespace Mesen.GUI.Forms
|
||||||
private void OnNotificationReceived(NotificationEventArgs e)
|
private void OnNotificationReceived(NotificationEventArgs e)
|
||||||
{
|
{
|
||||||
switch(e.NotificationType) {
|
switch(e.NotificationType) {
|
||||||
case ConsoleNotificationType.CodeBreak:
|
case ConsoleNotificationType.ResolutionChanged:
|
||||||
|
ScreenSize size = EmuApi.GetScreenSize(false);
|
||||||
|
this.BeginInvoke((Action)(() => {
|
||||||
|
UpdateViewerSize(size);
|
||||||
|
}));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateViewerSize(ScreenSize screenSize)
|
||||||
|
{
|
||||||
|
//this.Resize -= frmMain_Resize;
|
||||||
|
|
||||||
|
//if(forceUpdate || (!_customSize && this.WindowState != FormWindowState.Maximized)) {
|
||||||
|
Size newSize = new Size(screenSize.Width, screenSize.Height);
|
||||||
|
|
||||||
|
//UpdateScaleMenu(size.Scale);
|
||||||
|
this.ClientSize = new Size(newSize.Width, newSize.Height + pnlRenderer.Top);
|
||||||
|
//}
|
||||||
|
|
||||||
|
ctrlRenderer.Size = new Size(screenSize.Width, screenSize.Height);
|
||||||
|
ctrlRenderer.Top = (pnlRenderer.Height - ctrlRenderer.Height) / 2;
|
||||||
|
ctrlRenderer.Left = (pnlRenderer.Width - ctrlRenderer.Width) / 2;
|
||||||
|
|
||||||
|
//this.Resize += frmMain_Resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mnuVideoConfig_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using(frmVideoConfig frm = new frmVideoConfig()) {
|
||||||
|
frm.ShowDialog(sender, this);
|
||||||
|
}
|
||||||
|
ConfigManager.Config.Video.ApplyConfig();
|
||||||
|
}
|
||||||
|
|
||||||
private void mnuDebugger_Click(object sender, EventArgs e)
|
private void mnuDebugger_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DebugWindowManager.OpenDebugWindow(DebugWindow.Debugger);
|
DebugWindowManager.OpenDebugWindow(DebugWindow.Debugger);
|
||||||
|
|
21
UI/Interop/ConfigApi.cs
Normal file
21
UI/Interop/ConfigApi.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Mesen.GUI.Config;
|
||||||
|
using Mesen.GUI.Forms;
|
||||||
|
|
||||||
|
namespace Mesen.GUI
|
||||||
|
{
|
||||||
|
public class ConfigApi
|
||||||
|
{
|
||||||
|
private const string DllPath = "MesenSCore.dll";
|
||||||
|
|
||||||
|
[DllImport(DllPath)] public static extern void SetVideoConfig(VideoConfig config);
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,16 @@ namespace Mesen.GUI
|
||||||
|
|
||||||
[DllImport(DllPath)] public static extern void SetDisplayLanguage(Language lang);
|
[DllImport(DllPath)] public static extern void SetDisplayLanguage(Language lang);
|
||||||
|
|
||||||
|
[DllImport(DllPath)] public static extern ScreenSize GetScreenSize([MarshalAs(UnmanagedType.I1)]bool ignoreScale);
|
||||||
|
|
||||||
[DllImport(DllPath, EntryPoint = "GetLog")] private static extern IntPtr GetLogWrapper();
|
[DllImport(DllPath, EntryPoint = "GetLog")] private static extern IntPtr GetLogWrapper();
|
||||||
public static string GetLog() { return Utf8Marshaler.PtrToStringUtf8(EmuApi.GetLogWrapper()).Replace("\n", Environment.NewLine); }
|
public static string GetLog() { return Utf8Marshaler.PtrToStringUtf8(EmuApi.GetLogWrapper()).Replace("\n", Environment.NewLine); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ScreenSize
|
||||||
|
{
|
||||||
|
public Int32 Width;
|
||||||
|
public Int32 Height;
|
||||||
|
public double Scale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
12
UI/UI.csproj
12
UI/UI.csproj
|
@ -209,9 +209,11 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="CommandLineHelper.cs" />
|
<Compile Include="CommandLineHelper.cs" />
|
||||||
|
<Compile Include="Config\BaseConfig.cs" />
|
||||||
<Compile Include="Config\ConfigAttributes.cs" />
|
<Compile Include="Config\ConfigAttributes.cs" />
|
||||||
<Compile Include="Config\Configuration.cs" />
|
<Compile Include="Config\Configuration.cs" />
|
||||||
<Compile Include="Config\ConfigManager.cs" />
|
<Compile Include="Config\ConfigManager.cs" />
|
||||||
|
<Compile Include="Config\VideoConfig.cs" />
|
||||||
<Compile Include="Debugger\Breakpoints\Breakpoint.cs" />
|
<Compile Include="Debugger\Breakpoints\Breakpoint.cs" />
|
||||||
<Compile Include="Debugger\Breakpoints\BreakpointManager.cs" />
|
<Compile Include="Debugger\Breakpoints\BreakpointManager.cs" />
|
||||||
<Compile Include="Debugger\Breakpoints\ctrlBreakpoints.cs">
|
<Compile Include="Debugger\Breakpoints\ctrlBreakpoints.cs">
|
||||||
|
@ -462,6 +464,12 @@
|
||||||
<Compile Include="Forms\BaseInputForm.cs">
|
<Compile Include="Forms\BaseInputForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Forms\Config\frmVideoConfig.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Forms\Config\frmVideoConfig.Designer.cs">
|
||||||
|
<DependentUpon>frmVideoConfig.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Forms\EntityBinder.cs" />
|
<Compile Include="Forms\EntityBinder.cs" />
|
||||||
<Compile Include="Forms\frmLogWindow.cs">
|
<Compile Include="Forms\frmLogWindow.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
|
@ -480,6 +488,7 @@
|
||||||
<Compile Include="Forms\ResourceHelper.cs" />
|
<Compile Include="Forms\ResourceHelper.cs" />
|
||||||
<Compile Include="Forms\ResourcePath.cs" />
|
<Compile Include="Forms\ResourcePath.cs" />
|
||||||
<Compile Include="Interop\DebugApi.cs" />
|
<Compile Include="Interop\DebugApi.cs" />
|
||||||
|
<Compile Include="Interop\ConfigApi.cs" />
|
||||||
<Compile Include="Interop\EmuApi.cs" />
|
<Compile Include="Interop\EmuApi.cs" />
|
||||||
<Compile Include="Interop\NotificationListener.cs" />
|
<Compile Include="Interop\NotificationListener.cs" />
|
||||||
<Compile Include="Interop\Utf8Marshaler.cs" />
|
<Compile Include="Interop\Utf8Marshaler.cs" />
|
||||||
|
@ -585,6 +594,9 @@
|
||||||
<EmbeddedResource Include="Forms\BaseInputForm.resx">
|
<EmbeddedResource Include="Forms\BaseInputForm.resx">
|
||||||
<DependentUpon>BaseInputForm.cs</DependentUpon>
|
<DependentUpon>BaseInputForm.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Forms\Config\frmVideoConfig.resx">
|
||||||
|
<DependentUpon>frmVideoConfig.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Forms\frmLogWindow.resx">
|
<EmbeddedResource Include="Forms\frmLogWindow.resx">
|
||||||
<DependentUpon>frmLogWindow.cs</DependentUpon>
|
<DependentUpon>frmLogWindow.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
|
@ -417,9 +417,6 @@
|
||||||
<ClInclude Include="md5.h" />
|
<ClInclude Include="md5.h" />
|
||||||
<ClInclude Include="miniz.h" />
|
<ClInclude Include="miniz.h" />
|
||||||
<ClInclude Include="AutoResetEvent.h" />
|
<ClInclude Include="AutoResetEvent.h" />
|
||||||
<ClInclude Include="nes_ntsc.h" />
|
|
||||||
<ClInclude Include="nes_ntsc_config.h" />
|
|
||||||
<ClInclude Include="nes_ntsc_impl.h" />
|
|
||||||
<ClInclude Include="BaseCodec.h" />
|
<ClInclude Include="BaseCodec.h" />
|
||||||
<ClInclude Include="orfanidis_eq.h" />
|
<ClInclude Include="orfanidis_eq.h" />
|
||||||
<ClInclude Include="PlatformUtilities.h" />
|
<ClInclude Include="PlatformUtilities.h" />
|
||||||
|
@ -429,6 +426,9 @@
|
||||||
<ClInclude Include="Scale2x\scale3x.h" />
|
<ClInclude Include="Scale2x\scale3x.h" />
|
||||||
<ClInclude Include="Scale2x\scalebit.h" />
|
<ClInclude Include="Scale2x\scalebit.h" />
|
||||||
<ClInclude Include="sha1.h" />
|
<ClInclude Include="sha1.h" />
|
||||||
|
<ClInclude Include="snes_ntsc.h" />
|
||||||
|
<ClInclude Include="snes_ntsc_config.h" />
|
||||||
|
<ClInclude Include="snes_ntsc_impl.h" />
|
||||||
<ClInclude Include="stb_vorbis.h" />
|
<ClInclude Include="stb_vorbis.h" />
|
||||||
<ClInclude Include="StringUtilities.h" />
|
<ClInclude Include="StringUtilities.h" />
|
||||||
<ClInclude Include="SZReader.h" />
|
<ClInclude Include="SZReader.h" />
|
||||||
|
@ -543,7 +543,6 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="md5.cpp" />
|
<ClCompile Include="md5.cpp" />
|
||||||
<ClCompile Include="miniz.cpp" />
|
<ClCompile Include="miniz.cpp" />
|
||||||
<ClCompile Include="nes_ntsc.cpp" />
|
|
||||||
<ClCompile Include="PlatformUtilities.cpp" />
|
<ClCompile Include="PlatformUtilities.cpp" />
|
||||||
<ClCompile Include="PNGHelper.cpp" />
|
<ClCompile Include="PNGHelper.cpp" />
|
||||||
<ClCompile Include="AutoResetEvent.cpp" />
|
<ClCompile Include="AutoResetEvent.cpp" />
|
||||||
|
@ -585,6 +584,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="sha1.cpp" />
|
<ClCompile Include="sha1.cpp" />
|
||||||
<ClCompile Include="SimpleLock.cpp" />
|
<ClCompile Include="SimpleLock.cpp" />
|
||||||
|
<ClCompile Include="snes_ntsc.cpp" />
|
||||||
<ClCompile Include="Socket.cpp" />
|
<ClCompile Include="Socket.cpp" />
|
||||||
<ClCompile Include="stb_vorbis.cpp" />
|
<ClCompile Include="stb_vorbis.cpp" />
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
|
|
@ -80,15 +80,6 @@
|
||||||
<ClInclude Include="blip_buf.h">
|
<ClInclude Include="blip_buf.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="nes_ntsc.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="nes_ntsc_config.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="nes_ntsc_impl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="xBRZ\config.h">
|
<ClInclude Include="xBRZ\config.h">
|
||||||
<Filter>xBRZ</Filter>
|
<Filter>xBRZ</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -170,6 +161,15 @@
|
||||||
<ClInclude Include="FastString.h">
|
<ClInclude Include="FastString.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="snes_ntsc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="snes_ntsc_config.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="snes_ntsc_impl.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
@ -217,9 +217,6 @@
|
||||||
<ClCompile Include="blip_buf.cpp">
|
<ClCompile Include="blip_buf.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="nes_ntsc.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="xBRZ\xbrz.cpp">
|
<ClCompile Include="xBRZ\xbrz.cpp">
|
||||||
<Filter>xBRZ</Filter>
|
<Filter>xBRZ</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -292,5 +289,8 @@
|
||||||
<ClCompile Include="VirtualFile.cpp">
|
<ClCompile Include="VirtualFile.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="snes_ntsc.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,291 +0,0 @@
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
/* nes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
|
||||||
|
|
||||||
#include "nes_ntsc.h"
|
|
||||||
|
|
||||||
/* Copyright (C) 2006-2007 Shay Green. This module is free software; you
|
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
|
||||||
General Public License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
||||||
|
|
||||||
nes_ntsc_setup_t const nes_ntsc_monochrome = { 0,-1, 0, 0,.2, 0,.2,-.2,-.2,-1, 1, 0, 0, 0, 0 };
|
|
||||||
nes_ntsc_setup_t const nes_ntsc_composite = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 };
|
|
||||||
nes_ntsc_setup_t const nes_ntsc_svideo = { 0, 0, 0, 0,.2, 0,.2, -1, -1, 0, 1, 0, 0, 0, 0 };
|
|
||||||
nes_ntsc_setup_t const nes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, 1, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
#define alignment_count 3
|
|
||||||
#define burst_count 3
|
|
||||||
#define rescale_in 8
|
|
||||||
#define rescale_out 7
|
|
||||||
|
|
||||||
#define artifacts_mid 1.0f
|
|
||||||
#define fringing_mid 1.0f
|
|
||||||
#define std_decoder_hue -15
|
|
||||||
|
|
||||||
#define STD_HUE_CONDITION( setup ) !(setup->base_palette || setup->palette)
|
|
||||||
|
|
||||||
#include "nes_ntsc_impl.h"
|
|
||||||
|
|
||||||
/* 3 input pixels -> 8 composite samples */
|
|
||||||
pixel_info_t const nes_ntsc_pixels [alignment_count] = {
|
|
||||||
{ PIXEL_OFFSET( -4, -9 ), { 1, 1, .6667f, 0 } },
|
|
||||||
{ PIXEL_OFFSET( -2, -7 ), { .3333f, 1, 1, .3333f } },
|
|
||||||
{ PIXEL_OFFSET( 0, -5 ), { 0, .6667f, 1, 1 } },
|
|
||||||
};
|
|
||||||
|
|
||||||
static void merge_kernel_fields( nes_ntsc_rgb_t* io )
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
for ( n = burst_size; n; --n )
|
|
||||||
{
|
|
||||||
nes_ntsc_rgb_t p0 = io [burst_size * 0] + rgb_bias;
|
|
||||||
nes_ntsc_rgb_t p1 = io [burst_size * 1] + rgb_bias;
|
|
||||||
nes_ntsc_rgb_t p2 = io [burst_size * 2] + rgb_bias;
|
|
||||||
/* merge colors without losing precision */
|
|
||||||
io [burst_size * 0] =
|
|
||||||
((p0 + p1 - ((p0 ^ p1) & nes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
|
||||||
io [burst_size * 1] =
|
|
||||||
((p1 + p2 - ((p1 ^ p2) & nes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
|
||||||
io [burst_size * 2] =
|
|
||||||
((p2 + p0 - ((p2 ^ p0) & nes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
|
||||||
++io;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out )
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
for ( n = burst_count; n; --n )
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
for ( i = 0; i < rgb_kernel_size / 2; i++ )
|
|
||||||
{
|
|
||||||
nes_ntsc_rgb_t error = color -
|
|
||||||
out [i ] - out [(i+12)%14+14] - out [(i+10)%14+28] -
|
|
||||||
out [i + 7] - out [i + 5 +14] - out [i + 3 +28];
|
|
||||||
DISTRIBUTE_ERROR( i+3+28, i+5+14, i+7 );
|
|
||||||
}
|
|
||||||
out += alignment_count * rgb_kernel_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup )
|
|
||||||
{
|
|
||||||
int merge_fields;
|
|
||||||
int entry;
|
|
||||||
init_t impl;
|
|
||||||
float gamma_factor;
|
|
||||||
|
|
||||||
if ( !setup )
|
|
||||||
setup = &nes_ntsc_composite;
|
|
||||||
init( &impl, setup );
|
|
||||||
|
|
||||||
/* setup fast gamma */
|
|
||||||
{
|
|
||||||
float gamma = (float) setup->gamma * -0.5f;
|
|
||||||
if ( STD_HUE_CONDITION( setup ) )
|
|
||||||
gamma += 0.1333f;
|
|
||||||
|
|
||||||
gamma_factor = (float) pow( (float) fabs( gamma ), 0.73f );
|
|
||||||
if ( gamma < 0 )
|
|
||||||
gamma_factor = -gamma_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
merge_fields = setup->merge_fields;
|
|
||||||
if ( setup->artifacts <= -1 && setup->fringing <= -1 )
|
|
||||||
merge_fields = 1;
|
|
||||||
|
|
||||||
for ( entry = 0; entry < nes_ntsc_palette_size; entry++ )
|
|
||||||
{
|
|
||||||
/* Base 64-color generation */
|
|
||||||
static float const lo_levels [4] = { -0.12f, 0.00f, 0.31f, 0.72f };
|
|
||||||
static float const hi_levels [4] = { 0.40f, 0.68f, 1.00f, 1.00f };
|
|
||||||
int level = entry >> 4 & 0x03;
|
|
||||||
float lo = lo_levels [level];
|
|
||||||
float hi = hi_levels [level];
|
|
||||||
|
|
||||||
int color = entry & 0x0F;
|
|
||||||
if ( color == 0 )
|
|
||||||
lo = hi;
|
|
||||||
if ( color == 0x0D )
|
|
||||||
hi = lo;
|
|
||||||
if ( color > 0x0D )
|
|
||||||
hi = lo = 0.0f;
|
|
||||||
|
|
||||||
{
|
|
||||||
/* phases [i] = cos( i * PI / 6 ) */
|
|
||||||
static float const phases [0x10 + 3] = {
|
|
||||||
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
|
|
||||||
1.0f, 0.866025f, 0.5f, 0.0f, -0.5f, -0.866025f,
|
|
||||||
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
|
|
||||||
1.0f
|
|
||||||
};
|
|
||||||
#define TO_ANGLE_SIN( color ) phases [color]
|
|
||||||
#define TO_ANGLE_COS( color ) phases [(color) + 3]
|
|
||||||
|
|
||||||
/* Convert raw waveform to YIQ */
|
|
||||||
float sat = (hi - lo) * 0.5f;
|
|
||||||
float i = TO_ANGLE_SIN( color ) * sat;
|
|
||||||
float q = TO_ANGLE_COS( color ) * sat;
|
|
||||||
float y = (hi + lo) * 0.5f;
|
|
||||||
|
|
||||||
/* Optionally use base palette instead */
|
|
||||||
if ( setup->base_palette )
|
|
||||||
{
|
|
||||||
unsigned char const* in = &setup->base_palette [(entry & 0x3F) * 3];
|
|
||||||
static float const to_float = 1.0f / 0xFF;
|
|
||||||
float r = to_float * in [0];
|
|
||||||
float g = to_float * in [1];
|
|
||||||
float b = to_float * in [2];
|
|
||||||
q = RGB_TO_YIQ( r, g, b, y, i );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply color emphasis */
|
|
||||||
#ifdef NES_NTSC_EMPHASIS
|
|
||||||
{
|
|
||||||
int tint = entry >> 6 & 7;
|
|
||||||
if ( tint && color <= 0x0D )
|
|
||||||
{
|
|
||||||
static float const atten_mul = 0.79399f;
|
|
||||||
static float const atten_sub = 0.0782838f;
|
|
||||||
|
|
||||||
if ( tint == 7 )
|
|
||||||
{
|
|
||||||
y = y * (atten_mul * 1.13f) - (atten_sub * 1.13f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static unsigned char const tints [8] = { 0, 6, 10, 8, 2, 4, 0, 0 };
|
|
||||||
int const tint_color = tints [tint];
|
|
||||||
float sat = hi * (0.5f - atten_mul * 0.5f) + atten_sub * 0.5f;
|
|
||||||
y -= sat * 0.5f;
|
|
||||||
if ( tint >= 3 && tint != 4 )
|
|
||||||
{
|
|
||||||
/* combined tint bits */
|
|
||||||
sat *= 0.6f;
|
|
||||||
y -= sat;
|
|
||||||
}
|
|
||||||
i += TO_ANGLE_SIN( tint_color ) * sat;
|
|
||||||
q += TO_ANGLE_COS( tint_color ) * sat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Optionally use palette instead */
|
|
||||||
if ( setup->palette )
|
|
||||||
{
|
|
||||||
unsigned char const* in = &setup->palette [entry * 3];
|
|
||||||
static float const to_float = 1.0f / 0xFF;
|
|
||||||
float r = to_float * in [0];
|
|
||||||
float g = to_float * in [1];
|
|
||||||
float b = to_float * in [2];
|
|
||||||
q = RGB_TO_YIQ( r, g, b, y, i );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply brightness, contrast, and gamma */
|
|
||||||
y *= (float) setup->contrast * 0.5f + 1;
|
|
||||||
/* adjustment reduces error when using input palette */
|
|
||||||
y += (float) setup->brightness * 0.5f - 0.5f / 256;
|
|
||||||
|
|
||||||
{
|
|
||||||
float r, g, b = YIQ_TO_RGB( y, i, q, default_decoder, float, r, g );
|
|
||||||
|
|
||||||
/* fast approximation of n = pow( n, gamma ) */
|
|
||||||
r = (r * gamma_factor - gamma_factor) * r + r;
|
|
||||||
g = (g * gamma_factor - gamma_factor) * g + g;
|
|
||||||
b = (b * gamma_factor - gamma_factor) * b + b;
|
|
||||||
|
|
||||||
q = RGB_TO_YIQ( r, g, b, y, i );
|
|
||||||
}
|
|
||||||
|
|
||||||
i *= rgb_unit;
|
|
||||||
q *= rgb_unit;
|
|
||||||
y *= rgb_unit;
|
|
||||||
y += rgb_offset;
|
|
||||||
|
|
||||||
/* Generate kernel */
|
|
||||||
{
|
|
||||||
int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g );
|
|
||||||
/* blue tends to overflow, so clamp it */
|
|
||||||
nes_ntsc_rgb_t rgb = PACK_RGB( r, g, (b < 0x3E0 ? b: 0x3E0) );
|
|
||||||
|
|
||||||
if ( setup->palette_out )
|
|
||||||
RGB_PALETTE_OUT( rgb, &setup->palette_out [entry * 3] );
|
|
||||||
|
|
||||||
if ( ntsc )
|
|
||||||
{
|
|
||||||
nes_ntsc_rgb_t* kernel = ntsc->table [entry];
|
|
||||||
gen_kernel( &impl, y, i, q, kernel );
|
|
||||||
if ( merge_fields )
|
|
||||||
merge_kernel_fields( kernel );
|
|
||||||
correct_errors( rgb, kernel );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NES_NTSC_NO_BLITTERS
|
|
||||||
|
|
||||||
void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* input, long in_row_width,
|
|
||||||
int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch )
|
|
||||||
{
|
|
||||||
int chunk_count = (in_width - 1) / nes_ntsc_in_chunk;
|
|
||||||
for ( ; in_height; --in_height )
|
|
||||||
{
|
|
||||||
NES_NTSC_IN_T const* line_in = input;
|
|
||||||
NES_NTSC_BEGIN_ROW( ntsc, burst_phase,
|
|
||||||
nes_ntsc_black, nes_ntsc_black, NES_NTSC_ADJ_IN( *line_in ) );
|
|
||||||
nes_ntsc_out_t* restrict line_out = (nes_ntsc_out_t*) rgb_out;
|
|
||||||
int n;
|
|
||||||
++line_in;
|
|
||||||
|
|
||||||
for ( n = chunk_count; n; --n )
|
|
||||||
{
|
|
||||||
/* order of input and output pixels must not be altered */
|
|
||||||
NES_NTSC_COLOR_IN( 0, NES_NTSC_ADJ_IN( line_in [0] ) );
|
|
||||||
NES_NTSC_RGB_OUT( 0, line_out [0], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 1, line_out [1], NES_NTSC_OUT_DEPTH );
|
|
||||||
|
|
||||||
NES_NTSC_COLOR_IN( 1, NES_NTSC_ADJ_IN( line_in [1] ) );
|
|
||||||
NES_NTSC_RGB_OUT( 2, line_out [2], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 3, line_out [3], NES_NTSC_OUT_DEPTH );
|
|
||||||
|
|
||||||
NES_NTSC_COLOR_IN( 2, NES_NTSC_ADJ_IN( line_in [2] ) );
|
|
||||||
NES_NTSC_RGB_OUT( 4, line_out [4], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 5, line_out [5], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 6, line_out [6], NES_NTSC_OUT_DEPTH );
|
|
||||||
|
|
||||||
line_in += 3;
|
|
||||||
line_out += 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finish final pixels */
|
|
||||||
NES_NTSC_COLOR_IN( 0, nes_ntsc_black );
|
|
||||||
NES_NTSC_RGB_OUT( 0, line_out [0], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 1, line_out [1], NES_NTSC_OUT_DEPTH );
|
|
||||||
|
|
||||||
NES_NTSC_COLOR_IN( 1, nes_ntsc_black );
|
|
||||||
NES_NTSC_RGB_OUT( 2, line_out [2], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 3, line_out [3], NES_NTSC_OUT_DEPTH );
|
|
||||||
|
|
||||||
NES_NTSC_COLOR_IN( 2, nes_ntsc_black );
|
|
||||||
NES_NTSC_RGB_OUT( 4, line_out [4], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 5, line_out [5], NES_NTSC_OUT_DEPTH );
|
|
||||||
NES_NTSC_RGB_OUT( 6, line_out [6], NES_NTSC_OUT_DEPTH );
|
|
||||||
|
|
||||||
burst_phase = (burst_phase + 1) % nes_ntsc_burst_count;
|
|
||||||
input += in_row_width;
|
|
||||||
rgb_out = (char*) rgb_out + out_pitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,199 +0,0 @@
|
||||||
#pragma once
|
|
||||||
/* NES NTSC video filter */
|
|
||||||
|
|
||||||
/* nes_ntsc 0.2.2 */
|
|
||||||
#ifndef NES_NTSC_H
|
|
||||||
#define NES_NTSC_H
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#define EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nes_ntsc_config.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown
|
|
||||||
in parenthesis and should remain fairly stable in future versions. */
|
|
||||||
typedef struct nes_ntsc_setup_t
|
|
||||||
{
|
|
||||||
/* Basic parameters */
|
|
||||||
double hue; /* -1 = -180 degrees +1 = +180 degrees */
|
|
||||||
double saturation; /* -1 = grayscale (0.0) +1 = oversaturated colors (2.0) */
|
|
||||||
double contrast; /* -1 = dark (0.5) +1 = light (1.5) */
|
|
||||||
double brightness; /* -1 = dark (0.5) +1 = light (1.5) */
|
|
||||||
double sharpness; /* edge contrast enhancement/blurring */
|
|
||||||
|
|
||||||
/* Advanced parameters */
|
|
||||||
double gamma; /* -1 = dark (1.5) +1 = light (0.5) */
|
|
||||||
double resolution; /* image resolution */
|
|
||||||
double artifacts; /* artifacts caused by color changes */
|
|
||||||
double fringing; /* color artifacts caused by brightness changes */
|
|
||||||
double bleed; /* color bleed (color resolution reduction) */
|
|
||||||
int merge_fields; /* if 1, merges even and odd fields together to reduce flicker */
|
|
||||||
float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */
|
|
||||||
|
|
||||||
unsigned char* palette_out; /* optional RGB palette out, 3 bytes per color */
|
|
||||||
|
|
||||||
/* You can replace the standard NES color generation with an RGB palette. The
|
|
||||||
first replaces all color generation, while the second replaces only the core
|
|
||||||
64-color generation and does standard color emphasis calculations on it. */
|
|
||||||
unsigned char const* palette;/* optional 512-entry RGB palette in, 3 bytes per color */
|
|
||||||
unsigned char const* base_palette;/* optional 64-entry RGB palette in, 3 bytes per color */
|
|
||||||
} nes_ntsc_setup_t;
|
|
||||||
|
|
||||||
/* Video format presets */
|
|
||||||
extern nes_ntsc_setup_t const nes_ntsc_composite; /* color bleeding + artifacts */
|
|
||||||
extern nes_ntsc_setup_t const nes_ntsc_svideo; /* color bleeding only */
|
|
||||||
extern nes_ntsc_setup_t const nes_ntsc_rgb; /* crisp image */
|
|
||||||
extern nes_ntsc_setup_t const nes_ntsc_monochrome;/* desaturated + artifacts */
|
|
||||||
|
|
||||||
#ifdef NES_NTSC_EMPHASIS
|
|
||||||
enum { nes_ntsc_palette_size = 64 * 8 };
|
|
||||||
#else
|
|
||||||
enum { nes_ntsc_palette_size = 64 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initializes and adjusts parameters. Can be called multiple times on the same
|
|
||||||
nes_ntsc_t object. Can pass NULL for either parameter. */
|
|
||||||
typedef struct nes_ntsc_t nes_ntsc_t;
|
|
||||||
EXPORT void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup );
|
|
||||||
|
|
||||||
/* Filters one or more rows of pixels. Input pixels are 6/9-bit palette indicies.
|
|
||||||
In_row_width is the number of pixels to get to the next input row. Out_pitch
|
|
||||||
is the number of *bytes* to get to the next output row. Output pixel format
|
|
||||||
is set by NES_NTSC_OUT_DEPTH (defaults to 16-bit RGB). */
|
|
||||||
EXPORT void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* nes_in,
|
|
||||||
long in_row_width, int burst_phase, int in_width, int in_height,
|
|
||||||
void* rgb_out, long out_pitch );
|
|
||||||
|
|
||||||
/* Number of output pixels written by blitter for given input width. Width might
|
|
||||||
be rounded down slightly; use NES_NTSC_IN_WIDTH() on result to find rounded
|
|
||||||
value. Guaranteed not to round 256 down at all. */
|
|
||||||
#define NES_NTSC_OUT_WIDTH( in_width ) \
|
|
||||||
((((in_width) - 1) / nes_ntsc_in_chunk + 1) * nes_ntsc_out_chunk)
|
|
||||||
|
|
||||||
/* Number of input pixels that will fit within given output width. Might be
|
|
||||||
rounded down slightly; use NES_NTSC_OUT_WIDTH() on result to find rounded
|
|
||||||
value. */
|
|
||||||
#define NES_NTSC_IN_WIDTH( out_width ) \
|
|
||||||
(((out_width) / nes_ntsc_out_chunk - 1) * nes_ntsc_in_chunk + 1)
|
|
||||||
|
|
||||||
|
|
||||||
/* Interface for user-defined custom blitters */
|
|
||||||
|
|
||||||
enum { nes_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
|
|
||||||
enum { nes_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
|
|
||||||
enum { nes_ntsc_black = 15 }; /* palette index for black */
|
|
||||||
enum { nes_ntsc_burst_count = 3 }; /* burst phase cycles through 0, 1, and 2 */
|
|
||||||
|
|
||||||
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
|
|
||||||
Use nes_ntsc_black for unused pixels. Declares variables, so must be before first
|
|
||||||
statement in a block (unless you're using C++). */
|
|
||||||
#define NES_NTSC_BEGIN_ROW( ntsc, burst, pixel0, pixel1, pixel2 ) \
|
|
||||||
char const* const ktable = \
|
|
||||||
(char const*) (ntsc)->table [0] + burst * (nes_ntsc_burst_size * sizeof (nes_ntsc_rgb_t));\
|
|
||||||
NES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, NES_NTSC_ENTRY_, ktable )
|
|
||||||
|
|
||||||
/* Begins input pixel */
|
|
||||||
#define NES_NTSC_COLOR_IN( in_index, color_in ) \
|
|
||||||
NES_NTSC_COLOR_IN_( in_index, color_in, NES_NTSC_ENTRY_, ktable )
|
|
||||||
|
|
||||||
/* Generates output pixel. Bits can be 24, 16, 15, 32 (treated as 24), or 0:
|
|
||||||
24: RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8 RGB)
|
|
||||||
16: RRRRRGGG GGGBBBBB (5-6-5 RGB)
|
|
||||||
15: RRRRRGG GGGBBBBB (5-5-5 RGB)
|
|
||||||
0: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format; x = junk bits) */
|
|
||||||
#define NES_NTSC_RGB_OUT( index, rgb_out, bits ) \
|
|
||||||
NES_NTSC_RGB_OUT_14_( index, rgb_out, bits, 0 )
|
|
||||||
|
|
||||||
|
|
||||||
/* private */
|
|
||||||
enum { nes_ntsc_entry_size = 128 };
|
|
||||||
typedef unsigned long nes_ntsc_rgb_t;
|
|
||||||
struct nes_ntsc_t {
|
|
||||||
nes_ntsc_rgb_t table [nes_ntsc_palette_size] [nes_ntsc_entry_size];
|
|
||||||
};
|
|
||||||
enum { nes_ntsc_burst_size = nes_ntsc_entry_size / nes_ntsc_burst_count };
|
|
||||||
|
|
||||||
#define NES_NTSC_ENTRY_( ktable, n ) \
|
|
||||||
(nes_ntsc_rgb_t const*) (ktable + (n) * (nes_ntsc_entry_size * sizeof (nes_ntsc_rgb_t)))
|
|
||||||
|
|
||||||
/* deprecated */
|
|
||||||
#define NES_NTSC_RGB24_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 24 )
|
|
||||||
#define NES_NTSC_RGB16_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 16 )
|
|
||||||
#define NES_NTSC_RGB15_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 15 )
|
|
||||||
#define NES_NTSC_RAW_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 0 )
|
|
||||||
|
|
||||||
enum { nes_ntsc_min_in_width = 256 };
|
|
||||||
enum { nes_ntsc_min_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_min_in_width ) };
|
|
||||||
|
|
||||||
enum { nes_ntsc_640_in_width = 271 };
|
|
||||||
enum { nes_ntsc_640_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_640_in_width ) };
|
|
||||||
enum { nes_ntsc_640_overscan_left = 8 };
|
|
||||||
enum { nes_ntsc_640_overscan_right = nes_ntsc_640_in_width - 256 - nes_ntsc_640_overscan_left };
|
|
||||||
|
|
||||||
enum { nes_ntsc_full_in_width = 283 };
|
|
||||||
enum { nes_ntsc_full_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_full_in_width ) };
|
|
||||||
enum { nes_ntsc_full_overscan_left = 16 };
|
|
||||||
enum { nes_ntsc_full_overscan_right = nes_ntsc_full_in_width - 256 - nes_ntsc_full_overscan_left };
|
|
||||||
|
|
||||||
/* common 3->7 ntsc macros */
|
|
||||||
#define NES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
|
|
||||||
unsigned const nes_ntsc_pixel0_ = (pixel0);\
|
|
||||||
nes_ntsc_rgb_t const* kernel0 = ENTRY( table, nes_ntsc_pixel0_ );\
|
|
||||||
unsigned const nes_ntsc_pixel1_ = (pixel1);\
|
|
||||||
nes_ntsc_rgb_t const* kernel1 = ENTRY( table, nes_ntsc_pixel1_ );\
|
|
||||||
unsigned const nes_ntsc_pixel2_ = (pixel2);\
|
|
||||||
nes_ntsc_rgb_t const* kernel2 = ENTRY( table, nes_ntsc_pixel2_ );\
|
|
||||||
nes_ntsc_rgb_t const* kernelx0;\
|
|
||||||
nes_ntsc_rgb_t const* kernelx1 = kernel0;\
|
|
||||||
nes_ntsc_rgb_t const* kernelx2 = kernel0
|
|
||||||
|
|
||||||
#define NES_NTSC_RGB_OUT_14_( x, rgb_out, bits, shift ) {\
|
|
||||||
nes_ntsc_rgb_t raw_ =\
|
|
||||||
kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\
|
|
||||||
kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\
|
|
||||||
NES_NTSC_CLAMP_( raw_, shift );\
|
|
||||||
NES_NTSC_RGB_OUT_( rgb_out, bits, shift );\
|
|
||||||
}
|
|
||||||
|
|
||||||
/* common ntsc macros */
|
|
||||||
#define nes_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
|
||||||
#define nes_ntsc_clamp_mask (nes_ntsc_rgb_builder * 3 / 2)
|
|
||||||
#define nes_ntsc_clamp_add (nes_ntsc_rgb_builder * 0x101)
|
|
||||||
#define NES_NTSC_CLAMP_( io, shift ) {\
|
|
||||||
nes_ntsc_rgb_t sub = (io) >> (9-(shift)) & nes_ntsc_clamp_mask;\
|
|
||||||
nes_ntsc_rgb_t clamp = nes_ntsc_clamp_add - sub;\
|
|
||||||
io |= clamp;\
|
|
||||||
clamp -= sub;\
|
|
||||||
io &= clamp;\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NES_NTSC_COLOR_IN_( index, color, ENTRY, table ) {\
|
|
||||||
unsigned color_;\
|
|
||||||
kernelx##index = kernel##index;\
|
|
||||||
kernel##index = (color_ = (color), ENTRY( table, color_ ));\
|
|
||||||
}
|
|
||||||
|
|
||||||
/* x is always zero except in snes_ntsc library */
|
|
||||||
#define NES_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
|
|
||||||
if ( bits == 16 )\
|
|
||||||
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
|
||||||
if ( bits == 32 || bits == 24 )\
|
|
||||||
rgb_out = (raw_>>(5-x)&0xFF0000)|(raw_>>(3-x)&0xFF00)|(raw_>>(1-x)&0xFF);\
|
|
||||||
if ( bits == 15 )\
|
|
||||||
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
|
|
||||||
if ( bits == 0 )\
|
|
||||||
rgb_out = raw_ << x;\
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,27 +0,0 @@
|
||||||
/* Configure library by modifying this file */
|
|
||||||
|
|
||||||
#ifndef NES_NTSC_CONFIG_H
|
|
||||||
#define NES_NTSC_CONFIG_H
|
|
||||||
|
|
||||||
/* Uncomment to enable emphasis support and use a 512 color palette instead
|
|
||||||
of the base 64 color palette. */
|
|
||||||
#define NES_NTSC_EMPHASIS 1
|
|
||||||
|
|
||||||
/* The following affect the built-in blitter only; a custom blitter can
|
|
||||||
handle things however it wants. */
|
|
||||||
|
|
||||||
/* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */
|
|
||||||
#define NES_NTSC_OUT_DEPTH 32
|
|
||||||
|
|
||||||
/* Type of input pixel values. You'll probably use unsigned short
|
|
||||||
if you enable emphasis above. */
|
|
||||||
#define NES_NTSC_IN_T unsigned short
|
|
||||||
|
|
||||||
/* Each raw pixel input value is passed through this. You might want to mask
|
|
||||||
the pixel index if you use the high bits as flags, etc. */
|
|
||||||
#define NES_NTSC_ADJ_IN( in ) in
|
|
||||||
|
|
||||||
/* For each pixel, this is the basic operation:
|
|
||||||
output_color = color_palette [NES_NTSC_ADJ_IN( NES_NTSC_IN_T )] */
|
|
||||||
|
|
||||||
#endif
|
|
252
Utilities/snes_ntsc.cpp
Normal file
252
Utilities/snes_ntsc.cpp
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
/* snes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
||||||
|
|
||||||
|
#include "snes_ntsc.h"
|
||||||
|
|
||||||
|
/* Copyright (C) 2006-2007 Shay Green. This module is free software; you
|
||||||
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
|
General Public License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
|
snes_ntsc_setup_t const snes_ntsc_monochrome = { 0,-1, 0, 0,.2, 0,.2,-.2,-.2,-1, 1, 0, 0 };
|
||||||
|
snes_ntsc_setup_t const snes_ntsc_composite = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
|
||||||
|
snes_ntsc_setup_t const snes_ntsc_svideo = { 0, 0, 0, 0,.2, 0,.2, -1, -1, 0, 1, 0, 0 };
|
||||||
|
snes_ntsc_setup_t const snes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, 1, 0, 0 };
|
||||||
|
|
||||||
|
#define alignment_count 3
|
||||||
|
#define burst_count 3
|
||||||
|
#define rescale_in 8
|
||||||
|
#define rescale_out 7
|
||||||
|
|
||||||
|
#define artifacts_mid 1.0f
|
||||||
|
#define fringing_mid 1.0f
|
||||||
|
#define std_decoder_hue 0
|
||||||
|
|
||||||
|
#define rgb_bits 7 /* half normal range to allow for doubled hires pixels */
|
||||||
|
#define gamma_size 32
|
||||||
|
|
||||||
|
#include "snes_ntsc_impl.h"
|
||||||
|
|
||||||
|
/* 3 input pixels -> 8 composite samples */
|
||||||
|
pixel_info_t const snes_ntsc_pixels [alignment_count] = {
|
||||||
|
{ PIXEL_OFFSET( -4, -9 ), { 1, 1, .6667f, 0 } },
|
||||||
|
{ PIXEL_OFFSET( -2, -7 ), { .3333f, 1, 1, .3333f } },
|
||||||
|
{ PIXEL_OFFSET( 0, -5 ), { 0, .6667f, 1, 1 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void merge_kernel_fields( snes_ntsc_rgb_t* io )
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
for ( n = burst_size; n; --n )
|
||||||
|
{
|
||||||
|
snes_ntsc_rgb_t p0 = io [burst_size * 0] + rgb_bias;
|
||||||
|
snes_ntsc_rgb_t p1 = io [burst_size * 1] + rgb_bias;
|
||||||
|
snes_ntsc_rgb_t p2 = io [burst_size * 2] + rgb_bias;
|
||||||
|
/* merge colors without losing precision */
|
||||||
|
io [burst_size * 0] =
|
||||||
|
((p0 + p1 - ((p0 ^ p1) & snes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||||
|
io [burst_size * 1] =
|
||||||
|
((p1 + p2 - ((p1 ^ p2) & snes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||||
|
io [burst_size * 2] =
|
||||||
|
((p2 + p0 - ((p2 ^ p0) & snes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||||
|
++io;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void correct_errors( snes_ntsc_rgb_t color, snes_ntsc_rgb_t* out )
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
for ( n = burst_count; n; --n )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for ( i = 0; i < rgb_kernel_size / 2; i++ )
|
||||||
|
{
|
||||||
|
snes_ntsc_rgb_t error = color -
|
||||||
|
out [i ] - out [(i+12)%14+14] - out [(i+10)%14+28] -
|
||||||
|
out [i + 7] - out [i + 5 +14] - out [i + 3 +28];
|
||||||
|
DISTRIBUTE_ERROR( i+3+28, i+5+14, i+7 );
|
||||||
|
}
|
||||||
|
out += alignment_count * rgb_kernel_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup )
|
||||||
|
{
|
||||||
|
int merge_fields;
|
||||||
|
int entry;
|
||||||
|
init_t impl;
|
||||||
|
if ( !setup )
|
||||||
|
setup = &snes_ntsc_composite;
|
||||||
|
init( &impl, setup );
|
||||||
|
|
||||||
|
merge_fields = setup->merge_fields;
|
||||||
|
if ( setup->artifacts <= -1 && setup->fringing <= -1 )
|
||||||
|
merge_fields = 1;
|
||||||
|
|
||||||
|
for ( entry = 0; entry < snes_ntsc_palette_size; entry++ )
|
||||||
|
{
|
||||||
|
/* Reduce number of significant bits of source color. Clearing the
|
||||||
|
low bits of R and B were least notictable. Modifying green was too
|
||||||
|
noticeable. */
|
||||||
|
int ir = entry >> 8 & 0x1E;
|
||||||
|
int ig = entry >> 4 & 0x1F;
|
||||||
|
int ib = entry << 1 & 0x1E;
|
||||||
|
|
||||||
|
#if SNES_NTSC_BSNES_COLORTBL
|
||||||
|
if ( setup->bsnes_colortbl )
|
||||||
|
{
|
||||||
|
int bgr15 = (ib << 10) | (ig << 5) | ir;
|
||||||
|
unsigned long rgb16 = setup->bsnes_colortbl [bgr15];
|
||||||
|
ir = rgb16 >> 11 & 0x1E;
|
||||||
|
ig = rgb16 >> 6 & 0x1F;
|
||||||
|
ib = rgb16 & 0x1E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
float rr = impl.to_float [ir];
|
||||||
|
float gg = impl.to_float [ig];
|
||||||
|
float bb = impl.to_float [ib];
|
||||||
|
|
||||||
|
float y, i, q = RGB_TO_YIQ( rr, gg, bb, y, i );
|
||||||
|
|
||||||
|
int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g );
|
||||||
|
snes_ntsc_rgb_t rgb = PACK_RGB( r, g, b );
|
||||||
|
|
||||||
|
snes_ntsc_rgb_t* out = ntsc->table [entry];
|
||||||
|
gen_kernel( &impl, y, i, q, out );
|
||||||
|
if ( merge_fields )
|
||||||
|
merge_kernel_fields( out );
|
||||||
|
correct_errors( rgb, out );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SNES_NTSC_NO_BLITTERS
|
||||||
|
|
||||||
|
void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width,
|
||||||
|
int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch )
|
||||||
|
{
|
||||||
|
int chunk_count = (in_width - 1) / snes_ntsc_in_chunk;
|
||||||
|
for ( ; in_height; --in_height )
|
||||||
|
{
|
||||||
|
SNES_NTSC_IN_T const* line_in = input;
|
||||||
|
SNES_NTSC_BEGIN_ROW( ntsc, burst_phase,
|
||||||
|
snes_ntsc_black, snes_ntsc_black, SNES_NTSC_ADJ_IN( *line_in ) );
|
||||||
|
snes_ntsc_out_t* restrict line_out = (snes_ntsc_out_t*) rgb_out;
|
||||||
|
int n;
|
||||||
|
++line_in;
|
||||||
|
|
||||||
|
for ( n = chunk_count; n; --n )
|
||||||
|
{
|
||||||
|
/* order of input and output pixels must not be altered */
|
||||||
|
SNES_NTSC_COLOR_IN( 0, SNES_NTSC_ADJ_IN( line_in [0] ) );
|
||||||
|
SNES_NTSC_RGB_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 1, SNES_NTSC_ADJ_IN( line_in [1] ) );
|
||||||
|
SNES_NTSC_RGB_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 2, SNES_NTSC_ADJ_IN( line_in [2] ) );
|
||||||
|
SNES_NTSC_RGB_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
line_in += 3;
|
||||||
|
line_out += 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finish final pixels */
|
||||||
|
SNES_NTSC_COLOR_IN( 0, snes_ntsc_black );
|
||||||
|
SNES_NTSC_RGB_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 1, snes_ntsc_black );
|
||||||
|
SNES_NTSC_RGB_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 2, snes_ntsc_black );
|
||||||
|
SNES_NTSC_RGB_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_RGB_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
burst_phase = (burst_phase + 1) % snes_ntsc_burst_count;
|
||||||
|
input += in_row_width;
|
||||||
|
rgb_out = (char*) rgb_out + out_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width,
|
||||||
|
int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch )
|
||||||
|
{
|
||||||
|
int chunk_count = (in_width - 2) / (snes_ntsc_in_chunk * 2);
|
||||||
|
for ( ; in_height; --in_height )
|
||||||
|
{
|
||||||
|
SNES_NTSC_IN_T const* line_in = input;
|
||||||
|
SNES_NTSC_HIRES_ROW( ntsc, burst_phase,
|
||||||
|
snes_ntsc_black, snes_ntsc_black, snes_ntsc_black,
|
||||||
|
SNES_NTSC_ADJ_IN( line_in [0] ),
|
||||||
|
SNES_NTSC_ADJ_IN( line_in [1] ) );
|
||||||
|
snes_ntsc_out_t* restrict line_out = (snes_ntsc_out_t*) rgb_out;
|
||||||
|
int n;
|
||||||
|
line_in += 2;
|
||||||
|
|
||||||
|
for ( n = chunk_count; n; --n )
|
||||||
|
{
|
||||||
|
/* twice as many input pixels per chunk */
|
||||||
|
SNES_NTSC_COLOR_IN( 0, SNES_NTSC_ADJ_IN( line_in [0] ) );
|
||||||
|
SNES_NTSC_HIRES_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 1, SNES_NTSC_ADJ_IN( line_in [1] ) );
|
||||||
|
SNES_NTSC_HIRES_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 2, SNES_NTSC_ADJ_IN( line_in [2] ) );
|
||||||
|
SNES_NTSC_HIRES_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 3, SNES_NTSC_ADJ_IN( line_in [3] ) );
|
||||||
|
SNES_NTSC_HIRES_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 4, SNES_NTSC_ADJ_IN( line_in [4] ) );
|
||||||
|
SNES_NTSC_HIRES_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 5, SNES_NTSC_ADJ_IN( line_in [5] ) );
|
||||||
|
SNES_NTSC_HIRES_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_HIRES_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
line_in += 6;
|
||||||
|
line_out += 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 0, snes_ntsc_black );
|
||||||
|
SNES_NTSC_HIRES_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 1, snes_ntsc_black );
|
||||||
|
SNES_NTSC_HIRES_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 2, snes_ntsc_black );
|
||||||
|
SNES_NTSC_HIRES_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 3, snes_ntsc_black );
|
||||||
|
SNES_NTSC_HIRES_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 4, snes_ntsc_black );
|
||||||
|
SNES_NTSC_HIRES_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
SNES_NTSC_COLOR_IN( 5, snes_ntsc_black );
|
||||||
|
SNES_NTSC_HIRES_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||||
|
SNES_NTSC_HIRES_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||||
|
|
||||||
|
burst_phase = (burst_phase + 1) % snes_ntsc_burst_count;
|
||||||
|
input += in_row_width;
|
||||||
|
rgb_out = (char*) rgb_out + out_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
206
Utilities/snes_ntsc.h
Normal file
206
Utilities/snes_ntsc.h
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
/* SNES NTSC video filter */
|
||||||
|
|
||||||
|
/* snes_ntsc 0.2.2 */
|
||||||
|
#ifndef SNES_NTSC_H
|
||||||
|
#define SNES_NTSC_H
|
||||||
|
|
||||||
|
#include "snes_ntsc_config.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown
|
||||||
|
in parenthesis and should remain fairly stable in future versions. */
|
||||||
|
typedef struct snes_ntsc_setup_t
|
||||||
|
{
|
||||||
|
/* Basic parameters */
|
||||||
|
double hue; /* -1 = -180 degrees +1 = +180 degrees */
|
||||||
|
double saturation; /* -1 = grayscale (0.0) +1 = oversaturated colors (2.0) */
|
||||||
|
double contrast; /* -1 = dark (0.5) +1 = light (1.5) */
|
||||||
|
double brightness; /* -1 = dark (0.5) +1 = light (1.5) */
|
||||||
|
double sharpness; /* edge contrast enhancement/blurring */
|
||||||
|
|
||||||
|
/* Advanced parameters */
|
||||||
|
double gamma; /* -1 = dark (1.5) +1 = light (0.5) */
|
||||||
|
double resolution; /* image resolution */
|
||||||
|
double artifacts; /* artifacts caused by color changes */
|
||||||
|
double fringing; /* color artifacts caused by brightness changes */
|
||||||
|
double bleed; /* color bleed (color resolution reduction) */
|
||||||
|
int merge_fields; /* if 1, merges even and odd fields together to reduce flicker */
|
||||||
|
float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */
|
||||||
|
|
||||||
|
unsigned long const* bsnes_colortbl; /* undocumented; set to 0 */
|
||||||
|
} snes_ntsc_setup_t;
|
||||||
|
|
||||||
|
/* Video format presets */
|
||||||
|
extern snes_ntsc_setup_t const snes_ntsc_composite; /* color bleeding + artifacts */
|
||||||
|
extern snes_ntsc_setup_t const snes_ntsc_svideo; /* color bleeding only */
|
||||||
|
extern snes_ntsc_setup_t const snes_ntsc_rgb; /* crisp image */
|
||||||
|
extern snes_ntsc_setup_t const snes_ntsc_monochrome;/* desaturated + artifacts */
|
||||||
|
|
||||||
|
/* Initializes and adjusts parameters. Can be called multiple times on the same
|
||||||
|
snes_ntsc_t object. Can pass NULL for either parameter. */
|
||||||
|
typedef struct snes_ntsc_t snes_ntsc_t;
|
||||||
|
void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup );
|
||||||
|
|
||||||
|
/* Filters one or more rows of pixels. Input pixel format is set by SNES_NTSC_IN_FORMAT
|
||||||
|
and output RGB depth is set by SNES_NTSC_OUT_DEPTH. Both default to 16-bit RGB.
|
||||||
|
In_row_width is the number of pixels to get to the next input row. Out_pitch
|
||||||
|
is the number of *bytes* to get to the next output row. */
|
||||||
|
void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input,
|
||||||
|
long in_row_width, int burst_phase, int in_width, int in_height,
|
||||||
|
void* rgb_out, long out_pitch );
|
||||||
|
|
||||||
|
void snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input,
|
||||||
|
long in_row_width, int burst_phase, int in_width, int in_height,
|
||||||
|
void* rgb_out, long out_pitch );
|
||||||
|
|
||||||
|
/* Number of output pixels written by low-res blitter for given input width. Width
|
||||||
|
might be rounded down slightly; use SNES_NTSC_IN_WIDTH() on result to find rounded
|
||||||
|
value. Guaranteed not to round 256 down at all. */
|
||||||
|
#define SNES_NTSC_OUT_WIDTH( in_width ) \
|
||||||
|
((((in_width) - 1) / snes_ntsc_in_chunk + 1) * snes_ntsc_out_chunk)
|
||||||
|
|
||||||
|
/* Number of low-res input pixels that will fit within given output width. Might be
|
||||||
|
rounded down slightly; use SNES_NTSC_OUT_WIDTH() on result to find rounded
|
||||||
|
value. */
|
||||||
|
#define SNES_NTSC_IN_WIDTH( out_width ) \
|
||||||
|
(((out_width) / snes_ntsc_out_chunk - 1) * snes_ntsc_in_chunk + 1)
|
||||||
|
|
||||||
|
|
||||||
|
/* Interface for user-defined custom blitters */
|
||||||
|
|
||||||
|
enum { snes_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
|
||||||
|
enum { snes_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
|
||||||
|
enum { snes_ntsc_black = 0 }; /* palette index for black */
|
||||||
|
enum { snes_ntsc_burst_count = 3 }; /* burst phase cycles through 0, 1, and 2 */
|
||||||
|
|
||||||
|
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
|
||||||
|
Use snes_ntsc_black for unused pixels. Declares variables, so must be before first
|
||||||
|
statement in a block (unless you're using C++). */
|
||||||
|
#define SNES_NTSC_BEGIN_ROW( ntsc, burst, pixel0, pixel1, pixel2 ) \
|
||||||
|
char const* ktable = \
|
||||||
|
(char const*) (ntsc)->table + burst * (snes_ntsc_burst_size * sizeof (snes_ntsc_rgb_t));\
|
||||||
|
SNES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, SNES_NTSC_IN_FORMAT, ktable )
|
||||||
|
|
||||||
|
/* Begins input pixel */
|
||||||
|
#define SNES_NTSC_COLOR_IN( index, color ) \
|
||||||
|
SNES_NTSC_COLOR_IN_( index, color, SNES_NTSC_IN_FORMAT, ktable )
|
||||||
|
|
||||||
|
/* Generates output pixel. Bits can be 24, 16, 15, 14, 32 (treated as 24), or 0:
|
||||||
|
24: RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8 RGB)
|
||||||
|
16: RRRRRGGG GGGBBBBB (5-6-5 RGB)
|
||||||
|
15: RRRRRGG GGGBBBBB (5-5-5 RGB)
|
||||||
|
14: BBBBBGG GGGRRRRR (5-5-5 BGR, native SNES format)
|
||||||
|
0: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format; x = junk bits) */
|
||||||
|
#define SNES_NTSC_RGB_OUT( index, rgb_out, bits ) \
|
||||||
|
SNES_NTSC_RGB_OUT_14_( index, rgb_out, bits, 1 )
|
||||||
|
|
||||||
|
/* Hires equivalents */
|
||||||
|
#define SNES_NTSC_HIRES_ROW( ntsc, burst, pixel1, pixel2, pixel3, pixel4, pixel5 ) \
|
||||||
|
char const* ktable = \
|
||||||
|
(char const*) (ntsc)->table + burst * (snes_ntsc_burst_size * sizeof (snes_ntsc_rgb_t));\
|
||||||
|
unsigned const snes_ntsc_pixel1_ = (pixel1);\
|
||||||
|
snes_ntsc_rgb_t const* kernel1 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel1_ );\
|
||||||
|
unsigned const snes_ntsc_pixel2_ = (pixel2);\
|
||||||
|
snes_ntsc_rgb_t const* kernel2 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel2_ );\
|
||||||
|
unsigned const snes_ntsc_pixel3_ = (pixel3);\
|
||||||
|
snes_ntsc_rgb_t const* kernel3 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel3_ );\
|
||||||
|
unsigned const snes_ntsc_pixel4_ = (pixel4);\
|
||||||
|
snes_ntsc_rgb_t const* kernel4 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel4_ );\
|
||||||
|
unsigned const snes_ntsc_pixel5_ = (pixel5);\
|
||||||
|
snes_ntsc_rgb_t const* kernel5 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel5_ );\
|
||||||
|
snes_ntsc_rgb_t const* kernel0 = kernel1;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx0;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx1 = kernel1;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx2 = kernel1;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx3 = kernel1;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx4 = kernel1;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx5 = kernel1
|
||||||
|
|
||||||
|
#define SNES_NTSC_HIRES_OUT( x, rgb_out, bits ) {\
|
||||||
|
snes_ntsc_rgb_t raw_ =\
|
||||||
|
kernel0 [ x ] + kernel2 [(x+5)%7+14] + kernel4 [(x+3)%7+28] +\
|
||||||
|
kernelx0 [(x+7)%7+7] + kernelx2 [(x+5)%7+21] + kernelx4 [(x+3)%7+35] +\
|
||||||
|
kernel1 [(x+6)%7 ] + kernel3 [(x+4)%7+14] + kernel5 [(x+2)%7+28] +\
|
||||||
|
kernelx1 [(x+6)%7+7] + kernelx3 [(x+4)%7+21] + kernelx5 [(x+2)%7+35];\
|
||||||
|
SNES_NTSC_CLAMP_( raw_, 0 );\
|
||||||
|
SNES_NTSC_RGB_OUT_( rgb_out, (bits), 0 );\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
enum { snes_ntsc_entry_size = 128 };
|
||||||
|
enum { snes_ntsc_palette_size = 0x2000 };
|
||||||
|
typedef unsigned long snes_ntsc_rgb_t;
|
||||||
|
struct snes_ntsc_t {
|
||||||
|
snes_ntsc_rgb_t table [snes_ntsc_palette_size] [snes_ntsc_entry_size];
|
||||||
|
};
|
||||||
|
enum { snes_ntsc_burst_size = snes_ntsc_entry_size / snes_ntsc_burst_count };
|
||||||
|
|
||||||
|
#define SNES_NTSC_RGB16( ktable, n ) \
|
||||||
|
(snes_ntsc_rgb_t const*) (ktable + ((n & 0x001E) | (n >> 1 & 0x03E0) | (n >> 2 & 0x3C00)) * \
|
||||||
|
(snes_ntsc_entry_size / 2 * sizeof (snes_ntsc_rgb_t)))
|
||||||
|
|
||||||
|
#define SNES_NTSC_BGR15( ktable, n ) \
|
||||||
|
(snes_ntsc_rgb_t const*) (ktable + ((n << 9 & 0x3C00) | (n & 0x03E0) | (n >> 10 & 0x001E)) * \
|
||||||
|
(snes_ntsc_entry_size / 2 * sizeof (snes_ntsc_rgb_t)))
|
||||||
|
|
||||||
|
/* common 3->7 ntsc macros */
|
||||||
|
#define SNES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
|
||||||
|
unsigned const snes_ntsc_pixel0_ = (pixel0);\
|
||||||
|
snes_ntsc_rgb_t const* kernel0 = ENTRY( table, snes_ntsc_pixel0_ );\
|
||||||
|
unsigned const snes_ntsc_pixel1_ = (pixel1);\
|
||||||
|
snes_ntsc_rgb_t const* kernel1 = ENTRY( table, snes_ntsc_pixel1_ );\
|
||||||
|
unsigned const snes_ntsc_pixel2_ = (pixel2);\
|
||||||
|
snes_ntsc_rgb_t const* kernel2 = ENTRY( table, snes_ntsc_pixel2_ );\
|
||||||
|
snes_ntsc_rgb_t const* kernelx0;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx1 = kernel0;\
|
||||||
|
snes_ntsc_rgb_t const* kernelx2 = kernel0
|
||||||
|
|
||||||
|
#define SNES_NTSC_RGB_OUT_14_( x, rgb_out, bits, shift ) {\
|
||||||
|
snes_ntsc_rgb_t raw_ =\
|
||||||
|
kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\
|
||||||
|
kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\
|
||||||
|
SNES_NTSC_CLAMP_( raw_, shift );\
|
||||||
|
SNES_NTSC_RGB_OUT_( rgb_out, bits, shift );\
|
||||||
|
}
|
||||||
|
|
||||||
|
/* common ntsc macros */
|
||||||
|
#define snes_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
||||||
|
#define snes_ntsc_clamp_mask (snes_ntsc_rgb_builder * 3 / 2)
|
||||||
|
#define snes_ntsc_clamp_add (snes_ntsc_rgb_builder * 0x101)
|
||||||
|
#define SNES_NTSC_CLAMP_( io, shift ) {\
|
||||||
|
snes_ntsc_rgb_t sub = (io) >> (9-(shift)) & snes_ntsc_clamp_mask;\
|
||||||
|
snes_ntsc_rgb_t clamp = snes_ntsc_clamp_add - sub;\
|
||||||
|
io |= clamp;\
|
||||||
|
clamp -= sub;\
|
||||||
|
io &= clamp;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SNES_NTSC_COLOR_IN_( index, color, ENTRY, table ) {\
|
||||||
|
unsigned color_;\
|
||||||
|
kernelx##index = kernel##index;\
|
||||||
|
kernel##index = (color_ = (color), ENTRY( table, color_ ));\
|
||||||
|
}
|
||||||
|
|
||||||
|
/* x is always zero except in snes_ntsc library */
|
||||||
|
#define SNES_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
|
||||||
|
if ( bits == 16 )\
|
||||||
|
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
||||||
|
if ( bits == 24 || bits == 32 )\
|
||||||
|
rgb_out = 0xFF000000|(raw_>>(5-x)&0xFF0000)|(raw_>>(3-x)&0xFF00)|(raw_>>(1-x)&0xFF);\
|
||||||
|
if ( bits == 15 )\
|
||||||
|
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
|
||||||
|
if ( bits == 14 )\
|
||||||
|
rgb_out = (raw_>>(24-x)& 0x001F)|(raw_>>(9-x)&0x03E0)|(raw_<<(6+x)&0x7C00);\
|
||||||
|
if ( bits == 0 )\
|
||||||
|
rgb_out = raw_ << x;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
26
Utilities/snes_ntsc_config.h
Normal file
26
Utilities/snes_ntsc_config.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* Configure library by modifying this file */
|
||||||
|
|
||||||
|
#ifndef SNES_NTSC_CONFIG_H
|
||||||
|
#define SNES_NTSC_CONFIG_H
|
||||||
|
|
||||||
|
/* Format of source pixels */
|
||||||
|
/* #define SNES_NTSC_IN_FORMAT SNES_NTSC_RGB16 */
|
||||||
|
#define SNES_NTSC_IN_FORMAT SNES_NTSC_BGR15
|
||||||
|
|
||||||
|
/* The following affect the built-in blitter only; a custom blitter can
|
||||||
|
handle things however it wants. */
|
||||||
|
|
||||||
|
/* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */
|
||||||
|
#define SNES_NTSC_OUT_DEPTH 32
|
||||||
|
|
||||||
|
/* Type of input pixel values */
|
||||||
|
#define SNES_NTSC_IN_T unsigned short
|
||||||
|
|
||||||
|
/* Each raw pixel input value is passed through this. You might want to mask
|
||||||
|
the pixel index if you use the high bits as flags, etc. */
|
||||||
|
#define SNES_NTSC_ADJ_IN( in ) in
|
||||||
|
|
||||||
|
/* For each pixel, this is the basic operation:
|
||||||
|
output_color = SNES_NTSC_ADJ_IN( SNES_NTSC_IN_T ) */
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,4 @@
|
||||||
/* nes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
/* snes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
||||||
|
|
||||||
/* Common implementation of NTSC filters */
|
/* Common implementation of NTSC filters */
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
#define rgb_unit (1 << rgb_bits)
|
#define rgb_unit (1 << rgb_bits)
|
||||||
#define rgb_offset (rgb_unit * 2 + 0.5f)
|
#define rgb_offset (rgb_unit * 2 + 0.5f)
|
||||||
|
|
||||||
enum { burst_size = nes_ntsc_entry_size / burst_count };
|
enum { burst_size = snes_ntsc_entry_size / burst_count };
|
||||||
enum { kernel_half = 16 };
|
enum { kernel_half = 16 };
|
||||||
enum { kernel_size = kernel_half * 2 + 1 };
|
enum { kernel_size = kernel_half * 2 + 1 };
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ typedef struct init_t
|
||||||
i = t;\
|
i = t;\
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_filters( init_t* impl, nes_ntsc_setup_t const* setup )
|
static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup )
|
||||||
{
|
{
|
||||||
#if rescale_out > 1
|
#if rescale_out > 1
|
||||||
float kernels [kernel_size * 2];
|
float kernels [kernel_size * 2];
|
||||||
|
@ -195,7 +195,7 @@ static void init_filters( init_t* impl, nes_ntsc_setup_t const* setup )
|
||||||
static float const default_decoder [6] =
|
static float const default_decoder [6] =
|
||||||
{ 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f };
|
{ 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f };
|
||||||
|
|
||||||
static void init( init_t* impl, nes_ntsc_setup_t const* setup )
|
static void init( init_t* impl, snes_ntsc_setup_t const* setup )
|
||||||
{
|
{
|
||||||
impl->brightness = (float) setup->brightness * (0.5f * rgb_unit) + rgb_offset;
|
impl->brightness = (float) setup->brightness * (0.5f * rgb_unit) + rgb_offset;
|
||||||
impl->contrast = (float) setup->contrast * (0.5f * rgb_unit) + rgb_unit;
|
impl->contrast = (float) setup->contrast * (0.5f * rgb_unit) + rgb_unit;
|
||||||
|
@ -285,7 +285,7 @@ static void init( init_t* impl, nes_ntsc_setup_t const* setup )
|
||||||
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
|
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
|
||||||
|
|
||||||
enum { rgb_kernel_size = burst_size / alignment_count };
|
enum { rgb_kernel_size = burst_size / alignment_count };
|
||||||
enum { rgb_bias = rgb_unit * 2 * nes_ntsc_rgb_builder };
|
enum { rgb_bias = rgb_unit * 2 * snes_ntsc_rgb_builder };
|
||||||
|
|
||||||
typedef struct pixel_info_t
|
typedef struct pixel_info_t
|
||||||
{
|
{
|
||||||
|
@ -309,10 +309,10 @@ typedef struct pixel_info_t
|
||||||
(1.0f - (((ntsc) + 100) & 2))
|
(1.0f - (((ntsc) + 100) & 2))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern pixel_info_t const nes_ntsc_pixels [alignment_count];
|
extern pixel_info_t const snes_ntsc_pixels [alignment_count];
|
||||||
|
|
||||||
/* Generate pixel at all burst phases and column alignments */
|
/* Generate pixel at all burst phases and column alignments */
|
||||||
static void gen_kernel( init_t* impl, float y, float i, float q, nes_ntsc_rgb_t* out )
|
static void gen_kernel( init_t* impl, float y, float i, float q, snes_ntsc_rgb_t* out )
|
||||||
{
|
{
|
||||||
/* generate for each scanline burst phase */
|
/* generate for each scanline burst phase */
|
||||||
float const* to_rgb = impl->to_rgb;
|
float const* to_rgb = impl->to_rgb;
|
||||||
|
@ -324,7 +324,7 @@ static void gen_kernel( init_t* impl, float y, float i, float q, nes_ntsc_rgb_t*
|
||||||
Convolve these with kernels which: filter respective components, apply
|
Convolve these with kernels which: filter respective components, apply
|
||||||
sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack
|
sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack
|
||||||
into integer. Based on algorithm by NewRisingSun. */
|
into integer. Based on algorithm by NewRisingSun. */
|
||||||
pixel_info_t const* pixel = nes_ntsc_pixels;
|
pixel_info_t const* pixel = snes_ntsc_pixels;
|
||||||
int alignment_remain = alignment_count;
|
int alignment_remain = alignment_count;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -377,7 +377,7 @@ static void gen_kernel( init_t* impl, float y, float i, float q, nes_ntsc_rgb_t*
|
||||||
while ( --burst_remain );
|
while ( --burst_remain );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out );
|
static void correct_errors( snes_ntsc_rgb_t color, snes_ntsc_rgb_t* out );
|
||||||
|
|
||||||
#if DISABLE_CORRECTION
|
#if DISABLE_CORRECTION
|
||||||
#define CORRECT_ERROR( a ) { out [i] += rgb_bias; }
|
#define CORRECT_ERROR( a ) { out [i] += rgb_bias; }
|
||||||
|
@ -385,8 +385,8 @@ static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out );
|
||||||
#else
|
#else
|
||||||
#define CORRECT_ERROR( a ) { out [a] += error; }
|
#define CORRECT_ERROR( a ) { out [a] += error; }
|
||||||
#define DISTRIBUTE_ERROR( a, b, c ) {\
|
#define DISTRIBUTE_ERROR( a, b, c ) {\
|
||||||
nes_ntsc_rgb_t fourth = (error + 2 * nes_ntsc_rgb_builder) >> 2;\
|
snes_ntsc_rgb_t fourth = (error + 2 * snes_ntsc_rgb_builder) >> 2;\
|
||||||
fourth &= (rgb_bias >> 1) - nes_ntsc_rgb_builder;\
|
fourth &= (rgb_bias >> 1) - snes_ntsc_rgb_builder;\
|
||||||
fourth -= rgb_bias >> 2;\
|
fourth -= rgb_bias >> 2;\
|
||||||
out [a] += fourth;\
|
out [a] += fourth;\
|
||||||
out [b] += fourth;\
|
out [b] += fourth;\
|
||||||
|
@ -398,8 +398,8 @@ static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out );
|
||||||
#define RGB_PALETTE_OUT( rgb, out_ )\
|
#define RGB_PALETTE_OUT( rgb, out_ )\
|
||||||
{\
|
{\
|
||||||
unsigned char* out = (out_);\
|
unsigned char* out = (out_);\
|
||||||
nes_ntsc_rgb_t clamped = (rgb);\
|
snes_ntsc_rgb_t clamped = (rgb);\
|
||||||
NES_NTSC_CLAMP_( clamped, (8 - rgb_bits) );\
|
SNES_NTSC_CLAMP_( clamped, (8 - rgb_bits) );\
|
||||||
out [0] = (unsigned char) (clamped >> 21);\
|
out [0] = (unsigned char) (clamped >> 21);\
|
||||||
out [1] = (unsigned char) (clamped >> 11);\
|
out [1] = (unsigned char) (clamped >> 11);\
|
||||||
out [2] = (unsigned char) (clamped >> 1);\
|
out [2] = (unsigned char) (clamped >> 1);\
|
||||||
|
@ -420,18 +420,18 @@ static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out );
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#if NES_NTSC_OUT_DEPTH <= 16
|
#if SNES_NTSC_OUT_DEPTH <= 16
|
||||||
#if USHRT_MAX == 0xFFFF
|
#if USHRT_MAX == 0xFFFF
|
||||||
typedef unsigned short nes_ntsc_out_t;
|
typedef unsigned short snes_ntsc_out_t;
|
||||||
#else
|
#else
|
||||||
#error "Need 16-bit int type"
|
#error "Need 16-bit int type"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#if UINT_MAX == 0xFFFFFFFF
|
#if UINT_MAX == 0xFFFFFFFF
|
||||||
typedef unsigned int nes_ntsc_out_t;
|
typedef unsigned int snes_ntsc_out_t;
|
||||||
#elif ULONG_MAX == 0xFFFFFFFF
|
#elif ULONG_MAX == 0xFFFFFFFF
|
||||||
typedef unsigned long nes_ntsc_out_t;
|
typedef unsigned long snes_ntsc_out_t;
|
||||||
#else
|
#else
|
||||||
#error "Need 32-bit int type"
|
#error "Need 32-bit int type"
|
||||||
#endif
|
#endif
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../Core/Debugger.h"
|
#include "../Core/Debugger.h"
|
||||||
#include "../Core/MessageManager.h"
|
#include "../Core/MessageManager.h"
|
||||||
#include "../Core/SettingTypes.h"
|
#include "../Core/SettingTypes.h"
|
||||||
|
#include "../Core/EmuSettings.h"
|
||||||
#include "../Utilities/UTF8Util.h"
|
#include "../Utilities/UTF8Util.h"
|
||||||
|
|
||||||
using namespace DirectX;
|
using namespace DirectX;
|
||||||
|
@ -40,20 +41,18 @@ void Renderer::SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t m
|
||||||
|
|
||||||
void Renderer::SetScreenSize(uint32_t width, uint32_t height)
|
void Renderer::SetScreenSize(uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
ScreenSize screenSize;
|
ScreenSize screenSize = _console->GetVideoDecoder()->GetScreenSize(false);
|
||||||
_console->GetVideoDecoder()->GetScreenSize(screenSize, false);
|
VideoConfig cfg = _console->GetSettings()->GetVideoConfig();
|
||||||
|
if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _newFullscreen != _fullscreen || _useBilinearInterpolation != cfg.UseBilinearInterpolation) {
|
||||||
//TODO _resizeFilter != _console->GetSettings()->GetVideoResizeFilter()
|
|
||||||
if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _newFullscreen != _fullscreen) {
|
|
||||||
auto frameLock = _frameLock.AcquireSafe();
|
auto frameLock = _frameLock.AcquireSafe();
|
||||||
auto textureLock = _textureLock.AcquireSafe();
|
auto textureLock = _textureLock.AcquireSafe();
|
||||||
_console->GetVideoDecoder()->GetScreenSize(screenSize, false);
|
screenSize = _console->GetVideoDecoder()->GetScreenSize(false);
|
||||||
if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _newFullscreen != _fullscreen) {
|
if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _newFullscreen != _fullscreen || _useBilinearInterpolation != cfg.UseBilinearInterpolation) {
|
||||||
_nesFrameHeight = height;
|
_nesFrameHeight = height;
|
||||||
_nesFrameWidth = width;
|
_nesFrameWidth = width;
|
||||||
_newFrameBufferSize = width*height;
|
_newFrameBufferSize = width*height;
|
||||||
|
|
||||||
bool needReset = _fullscreen != _newFullscreen;//TODO || _resizeFilter != _console->GetSettings()->GetVideoResizeFilter();
|
bool needReset = _fullscreen != _newFullscreen || _useBilinearInterpolation != cfg.UseBilinearInterpolation;
|
||||||
bool fullscreenResizeMode = _fullscreen && _newFullscreen;
|
bool fullscreenResizeMode = _fullscreen && _newFullscreen;
|
||||||
|
|
||||||
if(_pSwapChain && _fullscreen && !_newFullscreen) {
|
if(_pSwapChain && _fullscreen && !_newFullscreen) {
|
||||||
|
@ -278,7 +277,7 @@ HRESULT Renderer::InitDevice()
|
||||||
sd.BufferDesc.Width = _realScreenWidth;
|
sd.BufferDesc.Width = _realScreenWidth;
|
||||||
sd.BufferDesc.Height = _realScreenHeight;
|
sd.BufferDesc.Height = _realScreenHeight;
|
||||||
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
sd.BufferDesc.RefreshRate.Numerator = 60; //TODO _console->GetSettings()->GetExclusiveRefreshRate();
|
sd.BufferDesc.RefreshRate.Numerator = _console->GetSettings()->GetVideoConfig().ExclusiveFullscreenRefreshRate;
|
||||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
sd.Flags = _fullscreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
|
sd.Flags = _fullscreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
|
||||||
|
@ -401,12 +400,12 @@ HRESULT Renderer::InitDevice()
|
||||||
|
|
||||||
HRESULT Renderer::CreateSamplerState()
|
HRESULT Renderer::CreateSamplerState()
|
||||||
{
|
{
|
||||||
_resizeFilter = VideoResizeFilter::NearestNeighbor; //TODO _console->GetSettings()->GetVideoResizeFilter();
|
_useBilinearInterpolation = _console->GetSettings()->GetVideoConfig().UseBilinearInterpolation;
|
||||||
|
|
||||||
//Sample state
|
//Sample state
|
||||||
D3D11_SAMPLER_DESC samplerDesc;
|
D3D11_SAMPLER_DESC samplerDesc;
|
||||||
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
|
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
|
||||||
samplerDesc.Filter = _resizeFilter == VideoResizeFilter::Bilinear ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
|
samplerDesc.Filter = _useBilinearInterpolation ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
@ -637,7 +636,7 @@ void Renderer::Render()
|
||||||
|
|
||||||
// Present the information rendered to the back buffer to the front buffer (the screen)
|
// Present the information rendered to the back buffer to the front buffer (the screen)
|
||||||
|
|
||||||
bool waitVSync = false; //TODO _console->GetSettings()->CheckFlag(EmulationFlags::VerticalSync)
|
bool waitVSync = _console->GetSettings()->GetVideoConfig().VerticalSync;
|
||||||
HRESULT hr = _pSwapChain->Present(waitVSync ? 1 : 0, 0);
|
HRESULT hr = _pSwapChain->Present(waitVSync ? 1 : 0, 0);
|
||||||
if(FAILED(hr)) {
|
if(FAILED(hr)) {
|
||||||
MessageManager::Log("SwapChain::Present() failed - Error:" + std::to_string(hr));
|
MessageManager::Log("SwapChain::Present() failed - Error:" + std::to_string(hr));
|
||||||
|
|
|
@ -42,7 +42,7 @@ private:
|
||||||
SimpleLock _frameLock;
|
SimpleLock _frameLock;
|
||||||
SimpleLock _textureLock;
|
SimpleLock _textureLock;
|
||||||
|
|
||||||
VideoResizeFilter _resizeFilter = VideoResizeFilter::NearestNeighbor;
|
bool _useBilinearInterpolation = false;
|
||||||
|
|
||||||
unique_ptr<SpriteFont> _font;
|
unique_ptr<SpriteFont> _font;
|
||||||
unique_ptr<SpriteFont> _largeFont;
|
unique_ptr<SpriteFont> _largeFont;
|
||||||
|
|
Loading…
Add table
Reference in a new issue