Video: Added option to rotate display by 90/180/270 degrees

This commit is contained in:
Souryo 2017-11-11 20:55:33 -05:00
parent 66197f2c09
commit fec2a2130b
24 changed files with 289 additions and 34 deletions

View file

@ -6,6 +6,7 @@
#include "Console.h"
#include "StandardController.h"
#include "ScaleFilter.h"
#include "RotateFilter.h"
BaseVideoFilter::BaseVideoFilter()
{
@ -52,7 +53,6 @@ void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer)
UpdateBufferSize();
OnBeforeApplyFilter();
ApplyFilter(ppuOutputBuffer);
_videoHud.DrawHud(GetOutputBuffer(), GetFrameInfo(), GetOverscan());
_frameLock.Release();
}
@ -77,14 +77,25 @@ void BaseVideoFilter::TakeScreenshot(VideoFilterType filterType, string filename
frameInfo = GetFrameInfo();
}
pngBuffer = frameBuffer;
uint32_t rotationAngle = EmulationSettings::GetScreenRotation();
shared_ptr<RotateFilter> rotateFilter;
if(rotationAngle > 0) {
rotateFilter.reset(new RotateFilter(rotationAngle));
pngBuffer = rotateFilter->ApplyFilter(pngBuffer, frameInfo.Width, frameInfo.Height);
frameInfo = rotateFilter->GetFrameInfo(frameInfo);
}
shared_ptr<ScaleFilter> scaleFilter = ScaleFilter::GetScaleFilter(filterType);
if(scaleFilter) {
pngBuffer = scaleFilter->ApplyFilter(frameBuffer, frameInfo.Width, frameInfo.Height);
pngBuffer = scaleFilter->ApplyFilter(pngBuffer, frameInfo.Width, frameInfo.Height);
frameInfo = scaleFilter->GetFrameInfo(frameInfo);
} else {
pngBuffer = frameBuffer;
}
VideoHud hud;
hud.DrawHud((uint8_t*)pngBuffer, frameInfo, EmulationSettings::GetOverscanDimensions());
if(!filename.empty()) {
PNGHelper::WritePNG(filename, pngBuffer, frameInfo.Width, frameInfo.Height);
} else {

View file

@ -8,7 +8,6 @@
class BaseVideoFilter
{
private:
VideoHud _videoHud;
uint8_t* _outputBuffer = nullptr;
uint32_t _bufferSize = 0;
SimpleLock _frameLock;

View file

@ -423,6 +423,7 @@
<ClInclude Include="HdData.h" />
<ClInclude Include="HdPackBuilder.h" />
<ClInclude Include="HdPackLoader.h" />
<ClInclude Include="RotateFilter.h" />
<ClInclude Include="LuaApi.h" />
<ClInclude Include="LuaCallHelper.h" />
<ClInclude Include="LuaScriptingContext.h" />
@ -845,6 +846,7 @@
<ClCompile Include="RewindData.cpp" />
<ClCompile Include="RewindManager.cpp" />
<ClCompile Include="RomLoader.cpp" />
<ClCompile Include="RotateFilter.cpp" />
<ClCompile Include="ScriptHost.cpp" />
<ClCompile Include="ScriptingContext.cpp" />
<ClCompile Include="ShortcutKeyHandler.cpp" />

View file

@ -1243,6 +1243,9 @@
<ClInclude Include="VirtualFile.h">
<Filter>Nes\RomLoader</Filter>
</ClInclude>
<ClInclude Include="RotateFilter.h">
<Filter>VideoDecoder</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -1509,5 +1512,8 @@
<ClCompile Include="VirtualFile.cpp">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="RotateFilter.cpp">
<Filter>VideoDecoder</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -74,6 +74,7 @@ PictureSettings EmulationSettings::_pictureSettings;
NtscFilterSettings EmulationSettings::_ntscFilterSettings;
bool EmulationSettings::_backgroundEnabled = true;
bool EmulationSettings::_spritesEnabled = true;
uint32_t EmulationSettings::_screenRotation = 0;
ConsoleType EmulationSettings::_consoleType = ConsoleType::Nes;
ExpansionPortDevice EmulationSettings::_expansionDevice = ExpansionPortDevice::None;

View file

@ -513,6 +513,7 @@ private:
static NtscFilterSettings _ntscFilterSettings;
static bool _backgroundEnabled;
static bool _spritesEnabled;
static uint32_t _screenRotation;
static ConsoleType _consoleType;
static ExpansionPortDevice _expansionDevice;
@ -1033,6 +1034,16 @@ public:
return _videoScale;
}
static void SetScreenRotation(uint32_t angle)
{
_screenRotation = angle;
}
static uint32_t GetScreenRotation()
{
return _screenRotation;
}
static uint32_t* GetRgbPalette()
{
return _currentPalette;

75
Core/RotateFilter.cpp Normal file
View file

@ -0,0 +1,75 @@
#include "RotateFilter.h"
#pragma once
RotateFilter::RotateFilter(uint32_t angle)
{
_angle = angle;
}
RotateFilter::~RotateFilter()
{
if(_outputBuffer) {
delete[] _outputBuffer;
}
}
void RotateFilter::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];
}
}
uint32_t RotateFilter::GetAngle()
{
return _angle;
}
uint32_t * RotateFilter::ApplyFilter(uint32_t * inputArgbBuffer, uint32_t width, uint32_t height)
{
UpdateOutputBuffer(width, height);
uint32_t *input = inputArgbBuffer;
if(_angle == 90) {
for(int i = (int)height - 1; i >= 0; i--) {
for(uint32_t j = 0; j < width; j++) {
_outputBuffer[j*height + i] = *input;
input++;
}
}
} else if(_angle == 180) {
for(int i = (int)height - 1; i >= 0; i--) {
for(int j = (int)width - 1; j >= 0; j--) {
_outputBuffer[i * width + j] = *input;
input++;
}
}
} else if(_angle == 270) {
for(uint32_t i = 0; i < height; i++) {
for(uint32_t j = 0; j < width; j++) {
_outputBuffer[j*height + i] = *input;
input++;
}
}
}
return _outputBuffer;
}
FrameInfo RotateFilter::GetFrameInfo(FrameInfo baseFrameInfo)
{
FrameInfo info = baseFrameInfo;
if(_angle % 180) {
info.Height = baseFrameInfo.Width;
info.Width = baseFrameInfo.Height;
info.OriginalHeight = baseFrameInfo.OriginalWidth;
info.OriginalWidth = baseFrameInfo.OriginalHeight;
}
return info;
}

22
Core/RotateFilter.h Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#include "stdafx.h"
#include "DefaultVideoFilter.h"
class RotateFilter
{
private:
uint32_t *_outputBuffer = nullptr;
uint32_t _angle = 0;
uint32_t _width = 0;
uint32_t _height = 0;
void UpdateOutputBuffer(uint32_t width, uint32_t height);
public:
RotateFilter(uint32_t angle);
~RotateFilter();
uint32_t GetAngle();
uint32_t* ApplyFilter(uint32_t *inputArgbBuffer, uint32_t width, uint32_t height);
FrameInfo GetFrameInfo(FrameInfo baseFrameInfo);
};

View file

@ -11,6 +11,7 @@
#include "RewindManager.h"
#include "PPU.h"
#include "HdNesPack.h"
#include "RotateFilter.h"
unique_ptr<VideoDecoder> VideoDecoder::Instance;
@ -43,7 +44,7 @@ VideoDecoder::~VideoDecoder()
FrameInfo VideoDecoder::GetFrameInfo()
{
return _videoFilter->GetFrameInfo();
return _lastFrameInfo;
}
void VideoDecoder::GetScreenSize(ScreenSize &size, bool ignoreScale)
@ -58,6 +59,11 @@ void VideoDecoder::GetScreenSize(ScreenSize &size, bool ignoreScale)
if(aspectRatio != 0.0) {
size.Width = (uint32_t)(frameInfo.OriginalHeight * scale * aspectRatio * ((double)frameInfo.Width / frameInfo.OriginalWidth));
}
if(EmulationSettings::GetScreenRotation() % 180) {
std::swap(size.Width, size.Height);
}
size.Scale = scale;
}
}
@ -86,6 +92,14 @@ void VideoDecoder::UpdateVideoFilter()
_hdFilterEnabled = true;
}
}
if(EmulationSettings::GetScreenRotation() == 0 && _rotateFilter) {
_rotateFilter.reset();
} else if(EmulationSettings::GetScreenRotation() > 0) {
if(!_rotateFilter || _rotateFilter->GetAngle() != EmulationSettings::GetScreenRotation()) {
_rotateFilter.reset(new RotateFilter(EmulationSettings::GetScreenRotation()));
}
}
}
void VideoDecoder::DecodeFrame()
@ -98,10 +112,21 @@ void VideoDecoder::DecodeFrame()
_videoFilter->SendFrame(_ppuOutputBuffer);
uint32_t* outputBuffer = (uint32_t*)_videoFilter->GetOutputBuffer();
if(_scaleFilter) {
outputBuffer = _scaleFilter->ApplyFilter(outputBuffer, _videoFilter->GetFrameInfo().Width, _videoFilter->GetFrameInfo().Height);
FrameInfo frameInfo = _videoFilter->GetFrameInfo();
if(_rotateFilter) {
outputBuffer = _rotateFilter->ApplyFilter(outputBuffer, frameInfo.Width, frameInfo.Height);
frameInfo = _rotateFilter->GetFrameInfo(frameInfo);
}
if(_scaleFilter) {
outputBuffer = _scaleFilter->ApplyFilter(outputBuffer, frameInfo.Width, frameInfo.Height);
frameInfo = _scaleFilter->GetFrameInfo(frameInfo);
}
VideoHud hud;
hud.DrawHud((uint8_t*)outputBuffer, frameInfo, _videoFilter->GetOverscan());
ScreenSize screenSize;
GetScreenSize(screenSize, true);
if(_previousScale != EmulationSettings::GetVideoScale() || screenSize.Height != _previousScreenSize.Height || screenSize.Width != _previousScreenSize.Width) {
@ -110,10 +135,7 @@ void VideoDecoder::DecodeFrame()
_previousScale = EmulationSettings::GetVideoScale();
_previousScreenSize = screenSize;
FrameInfo frameInfo = _videoFilter->GetFrameInfo();
if(_scaleFilter) {
frameInfo = _scaleFilter->GetFrameInfo(frameInfo);
}
_lastFrameInfo = frameInfo;
_frameChanged = false;

View file

@ -10,6 +10,7 @@ using std::thread;
class BaseVideoFilter;
class ScaleFilter;
class RotateFilter;
class IRenderingDevice;
struct HdPpuPixelInfo;
@ -39,10 +40,12 @@ private:
ScreenSize _previousScreenSize = {};
double _previousScale = 0;
FrameInfo _lastFrameInfo;
VideoFilterType _videoFilterType = VideoFilterType::None;
unique_ptr<BaseVideoFilter> _videoFilter;
shared_ptr<ScaleFilter> _scaleFilter;
shared_ptr<RotateFilter> _rotateFilter;
void UpdateVideoFilter();

View file

@ -21,7 +21,8 @@ void VideoHud::DrawHud(uint8_t *outputBuffer, FrameInfo frameInfo, OverscanDimen
bool VideoHud::DisplayControllerInput(int inputPort, uint8_t *outputBuffer, FrameInfo &frameInfo, OverscanDimensions &overscan, uint32_t displayIndex)
{
int scale = frameInfo.Width / overscan.GetScreenWidth();
bool axisInverted = (EmulationSettings::GetScreenRotation() % 180) != 0;
int scale = frameInfo.Width / (axisInverted ? overscan.GetScreenHeight() : overscan.GetScreenWidth());
uint32_t* rgbaBuffer = (uint32_t*)outputBuffer;
InputDisplaySettings settings = EmulationSettings::GetInputDisplaySettings();

View file

@ -20,6 +20,7 @@ namespace Mesen.GUI.Config
public VideoFilterType VideoFilter = VideoFilterType.None;
public bool UseBilinearInterpolation = false;
public VideoAspectRatio AspectRatio = VideoAspectRatio.NoStretching;
public ScreenRotation ScreenRotation = ScreenRotation.None;
[MinMax(0.1, 5.0)] public double CustomAspectRatio = 1.0;
public bool VerticalSync = false;
public bool UseHdPacks = false;
@ -78,6 +79,8 @@ namespace Mesen.GUI.Config
InteropEmu.SetOverscanDimensions(videoInfo.OverscanLeft, videoInfo.OverscanRight, videoInfo.OverscanTop, videoInfo.OverscanBottom);
InteropEmu.SetScreenRotation((UInt32)videoInfo.ScreenRotation);
InteropEmu.SetVideoFilter(videoInfo.VideoFilter);
InteropEmu.SetVideoResizeFilter(videoInfo.UseBilinearInterpolation ? VideoResizeFilter.Bilinear : VideoResizeFilter.NearestNeighbor);
InteropEmu.SetVideoScale(videoInfo.VideoScale <= 10 ? videoInfo.VideoScale : 2);

View file

@ -292,6 +292,7 @@
<Control ID="mnuPresetMonochrome">Monocrom</Control>
<Control ID="tpgAdvanced">Avançat</Control>
<Control ID="lblScreenRotation">Screen Rotation:</Control>
<Control ID="chkDisableBackground">Desactiva el fons</Control>
<Control ID="chkDisableSprites">Desactiva els sprites</Control>
<Control ID="chkForceBackgroundFirstColumn">Força l'aparició del fons a la primera columna</Control>
@ -765,6 +766,12 @@
<Value ID="Widescreen">Pantalla panoràmica (16:9)</Value>
<Value ID="Custom">Personalitzat</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">None</Value>
<Value ID="_90Degrees">90°</Value>
<Value ID="_180Degrees">180°</Value>
<Value ID="_270Degrees">270°</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">Cap</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -170,6 +170,12 @@
<Value ID="Widescreen">Widescreen (16:9)</Value>
<Value ID="Custom">Custom</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">None</Value>
<Value ID="_90Degrees">90°</Value>
<Value ID="_180Degrees">180°</Value>
<Value ID="_270Degrees">270°</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">None</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -292,6 +292,7 @@
<Control ID="mnuPresetMonochrome">Monocromo</Control>
<Control ID="tpgAdvanced">Avanzado</Control>
<Control ID="lblScreenRotation">Screen Rotation:</Control>
<Control ID="chkDisableBackground">Deshabilitar fondo</Control>
<Control ID="chkDisableSprites">Deshabilitar sprites</Control>
<Control ID="chkForceBackgroundFirstColumn">Forzar ver fondo en primera columna</Control>
@ -784,6 +785,12 @@
<Value ID="Widescreen">Pantalla panorámica (16:9)</Value>
<Value ID="Custom">Personalizado</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">None</Value>
<Value ID="_90Degrees">90°</Value>
<Value ID="_180Degrees">180°</Value>
<Value ID="_270Degrees">270°</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">Ninguno</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -294,6 +294,7 @@
<Control ID="mnuPresetMonochrome">Monochrome</Control>
<Control ID="tpgAdvanced">Avancé</Control>
<Control ID="lblScreenRotation">Rotation de l'écran :</Control>
<Control ID="chkDisableBackground">Désactiver l'arrière-plan</Control>
<Control ID="chkDisableSprites">Désactiver les sprites</Control>
<Control ID="chkForceBackgroundFirstColumn">Forcer l'affichage de l'arrière-plan dans la première colonne</Control>
@ -797,6 +798,12 @@
<Value ID="Widescreen">Écran large (16:9)</Value>
<Value ID="Custom">Personalisé</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">Aucune</Value>
<Value ID="_90Degrees">90°</Value>
<Value ID="_180Degrees">180°</Value>
<Value ID="_270Degrees">270°</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">Aucun</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -296,6 +296,7 @@
<Control ID="mnuPresetMonochrome">モノクロ</Control>
<Control ID="tpgAdvanced">詳細設定</Control>
<Control ID="lblScreenRotation">画面の回転:</Control>
<Control ID="chkDisableBackground">バックグラウンドを隠す</Control>
<Control ID="chkDisableSprites">スプライトを隠す</Control>
<Control ID="chkForceBackgroundFirstColumn">ゲームの設定を無視して、画面の一番左側にバックグラウンドを表す</Control>
@ -782,6 +783,12 @@
<Value ID="Widescreen">ワイド (16:9)</Value>
<Value ID="Custom">カスタム</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">なし</Value>
<Value ID="_90Degrees">90度</Value>
<Value ID="_180Degrees">180度</Value>
<Value ID="_270Degrees">270度</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">なし</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -292,6 +292,7 @@
<Control ID="mnuPresetMonochrome">Monocromo</Control>
<Control ID="tpgAdvanced">Avançado</Control>
<Control ID="lblScreenRotation">Screen Rotation:</Control>
<Control ID="chkDisableBackground">Desabilitar fundo</Control>
<Control ID="chkDisableSprites">Desabilitar sprites</Control>
<Control ID="chkForceBackgroundFirstColumn">Forçar ver fundo em primeira coluna</Control>
@ -782,6 +783,12 @@
<Value ID="Widescreen">Widescreen (16:9)</Value>
<Value ID="Custom">Personalizado</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">None</Value>
<Value ID="_90Degrees">90°</Value>
<Value ID="_180Degrees">180°</Value>
<Value ID="_270Degrees">270°</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">Nenhum</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -294,6 +294,7 @@
<Control ID="mnuPresetMonochrome">Monochrome</Control>
<Control ID="tpgAdvanced">Advanced</Control>
<Control ID="lblScreenRotation">Screen Rotation:</Control>
<Control ID="chkDisableBackground">Disable background</Control>
<Control ID="chkDisableSprites">Disable sprites</Control>
<Control ID="chkForceBackgroundFirstColumn">Force background display in first column</Control>
@ -787,6 +788,12 @@
<Value ID="Widescreen">Широкий экран (16:9)</Value>
<Value ID="Custom">Custom</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">None</Value>
<Value ID="_90Degrees">90°</Value>
<Value ID="_180Degrees">180°</Value>
<Value ID="_270Degrees">270°</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">Отсутствует</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -294,6 +294,7 @@
<Control ID="mnuPresetMonochrome">Монохромний</Control>
<Control ID="tpgAdvanced">Розширенi</Control>
<Control ID="lblScreenRotation">Screen Rotation:</Control>
<Control ID="chkDisableBackground">Відключити фон</Control>
<Control ID="chkDisableSprites">Відключити спрайти</Control>
<Control ID="chkForceBackgroundFirstColumn">Примусово показувати фон у першому стовпці</Control>
@ -787,6 +788,12 @@
<Value ID="Widescreen">Широкий екран (16:9)</Value>
<Value ID="Custom">Custom</Value>
</Enum>
<Enum ID="ScreenRotation">
<Value ID="None">None</Value>
<Value ID="_90Degrees">90°</Value>
<Value ID="_180Degrees">180°</Value>
<Value ID="_270Degrees">270°</Value>
</Enum>
<Enum ID="VideoFilterType">
<Value ID="None">Відсутнє</Value>
<Value ID="NTSC">NTSC</Value>

View file

@ -44,6 +44,7 @@ namespace Mesen.GUI.Forms.Config
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.tabMain = new System.Windows.Forms.TabControl();
this.tpgGeneral = new System.Windows.Forms.TabPage();
this.tpgPicture = new System.Windows.Forms.TabPage();
@ -124,7 +125,8 @@ namespace Mesen.GUI.Forms.Config
this.mnuPaletteSonyCxa2025As = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPaletteUnsaturated = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPaletteYuv = new System.Windows.Forms.ToolStripMenuItem();
this.chkIntegerFpsMode = new System.Windows.Forms.CheckBox();
this.lblScreenRotation = new System.Windows.Forms.Label();
this.cboScreenRotation = new System.Windows.Forms.ComboBox();
this.tlpMain.SuspendLayout();
this.flowLayoutPanel7.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picHdNesTooltip)).BeginInit();
@ -386,6 +388,18 @@ namespace Mesen.GUI.Forms.Config
this.chkShowFps.Text = "Show FPS";
this.chkShowFps.UseVisualStyleBackColor = true;
//
// 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, 49);
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;
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgGeneral);
@ -1274,16 +1288,20 @@ namespace Mesen.GUI.Forms.Config
//
// tableLayoutPanel9
//
this.tableLayoutPanel9.ColumnCount = 1;
this.tableLayoutPanel9.ColumnCount = 2;
this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel9.Controls.Add(this.chkDisableBackground, 0, 0);
this.tableLayoutPanel9.Controls.Add(this.chkDisableSprites, 0, 1);
this.tableLayoutPanel9.Controls.Add(this.chkForceBackgroundFirstColumn, 0, 2);
this.tableLayoutPanel9.Controls.Add(this.chkForceSpritesFirstColumn, 0, 3);
this.tableLayoutPanel9.Controls.Add(this.chkDisableBackground, 0, 1);
this.tableLayoutPanel9.Controls.Add(this.chkDisableSprites, 0, 2);
this.tableLayoutPanel9.Controls.Add(this.chkForceBackgroundFirstColumn, 0, 3);
this.tableLayoutPanel9.Controls.Add(this.chkForceSpritesFirstColumn, 0, 4);
this.tableLayoutPanel9.Controls.Add(this.lblScreenRotation, 0, 0);
this.tableLayoutPanel9.Controls.Add(this.cboScreenRotation, 1, 0);
this.tableLayoutPanel9.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel9.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel9.Name = "tableLayoutPanel9";
this.tableLayoutPanel9.RowCount = 5;
this.tableLayoutPanel9.RowCount = 6;
this.tableLayoutPanel9.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel9.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel9.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel9.RowStyles.Add(new System.Windows.Forms.RowStyle());
@ -1295,8 +1313,9 @@ namespace Mesen.GUI.Forms.Config
// chkDisableBackground
//
this.chkDisableBackground.Checked = false;
this.tableLayoutPanel9.SetColumnSpan(this.chkDisableBackground, 2);
this.chkDisableBackground.Dock = System.Windows.Forms.DockStyle.Fill;
this.chkDisableBackground.Location = new System.Drawing.Point(0, 0);
this.chkDisableBackground.Location = new System.Drawing.Point(0, 27);
this.chkDisableBackground.MinimumSize = new System.Drawing.Size(0, 21);
this.chkDisableBackground.Name = "chkDisableBackground";
this.chkDisableBackground.Size = new System.Drawing.Size(521, 23);
@ -1306,8 +1325,9 @@ namespace Mesen.GUI.Forms.Config
// chkDisableSprites
//
this.chkDisableSprites.Checked = false;
this.tableLayoutPanel9.SetColumnSpan(this.chkDisableSprites, 2);
this.chkDisableSprites.Dock = System.Windows.Forms.DockStyle.Fill;
this.chkDisableSprites.Location = new System.Drawing.Point(0, 23);
this.chkDisableSprites.Location = new System.Drawing.Point(0, 50);
this.chkDisableSprites.MinimumSize = new System.Drawing.Size(0, 21);
this.chkDisableSprites.Name = "chkDisableSprites";
this.chkDisableSprites.Size = new System.Drawing.Size(521, 23);
@ -1317,8 +1337,9 @@ namespace Mesen.GUI.Forms.Config
// chkForceBackgroundFirstColumn
//
this.chkForceBackgroundFirstColumn.Checked = false;
this.tableLayoutPanel9.SetColumnSpan(this.chkForceBackgroundFirstColumn, 2);
this.chkForceBackgroundFirstColumn.Dock = System.Windows.Forms.DockStyle.Fill;
this.chkForceBackgroundFirstColumn.Location = new System.Drawing.Point(0, 46);
this.chkForceBackgroundFirstColumn.Location = new System.Drawing.Point(0, 73);
this.chkForceBackgroundFirstColumn.MinimumSize = new System.Drawing.Size(0, 21);
this.chkForceBackgroundFirstColumn.Name = "chkForceBackgroundFirstColumn";
this.chkForceBackgroundFirstColumn.Size = new System.Drawing.Size(521, 23);
@ -1328,8 +1349,9 @@ namespace Mesen.GUI.Forms.Config
// chkForceSpritesFirstColumn
//
this.chkForceSpritesFirstColumn.Checked = false;
this.tableLayoutPanel9.SetColumnSpan(this.chkForceSpritesFirstColumn, 2);
this.chkForceSpritesFirstColumn.Dock = System.Windows.Forms.DockStyle.Fill;
this.chkForceSpritesFirstColumn.Location = new System.Drawing.Point(0, 69);
this.chkForceSpritesFirstColumn.Location = new System.Drawing.Point(0, 96);
this.chkForceSpritesFirstColumn.MinimumSize = new System.Drawing.Size(0, 21);
this.chkForceSpritesFirstColumn.Name = "chkForceSpritesFirstColumn";
this.chkForceSpritesFirstColumn.Size = new System.Drawing.Size(521, 23);
@ -1459,17 +1481,24 @@ namespace Mesen.GUI.Forms.Config
this.mnuPaletteYuv.Text = "YUV v3 (by FirebrandX)";
this.mnuPaletteYuv.Click += new System.EventHandler(this.mnuPaletteYuv_Click);
//
// chkIntegerFpsMode
// lblScreenRotation
//
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, 49);
this.chkIntegerFpsMode.Name = "chkIntegerFpsMode";
this.chkIntegerFpsMode.Size = new System.Drawing.Size(295, 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.lblScreenRotation.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblScreenRotation.AutoSize = true;
this.lblScreenRotation.Location = new System.Drawing.Point(3, 7);
this.lblScreenRotation.Name = "lblScreenRotation";
this.lblScreenRotation.Size = new System.Drawing.Size(87, 13);
this.lblScreenRotation.TabIndex = 4;
this.lblScreenRotation.Text = "Screen Rotation:";
//
// cboScreenRotation
//
this.cboScreenRotation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboScreenRotation.FormattingEnabled = true;
this.cboScreenRotation.Location = new System.Drawing.Point(96, 3);
this.cboScreenRotation.Name = "cboScreenRotation";
this.cboScreenRotation.Size = new System.Drawing.Size(77, 21);
this.cboScreenRotation.TabIndex = 5;
//
// frmVideoConfig
//
@ -1528,6 +1557,7 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel2.PerformLayout();
this.tpgAdvanced.ResumeLayout(false);
this.tableLayoutPanel9.ResumeLayout(false);
this.tableLayoutPanel9.PerformLayout();
this.contextPicturePresets.ResumeLayout(false);
this.contextPaletteList.ResumeLayout(false);
this.ResumeLayout(false);
@ -1631,5 +1661,7 @@ namespace Mesen.GUI.Forms.Config
private System.Windows.Forms.CheckBox chkShowColorIndexes;
private Debugger.ctrlPaletteDisplay ctrlPaletteDisplay;
private System.Windows.Forms.CheckBox chkIntegerFpsMode;
private System.Windows.Forms.Label lblScreenRotation;
private System.Windows.Forms.ComboBox cboScreenRotation;
}
}

View file

@ -36,6 +36,8 @@ namespace Mesen.GUI.Forms.Config
AddBinding("CustomAspectRatio", nudCustomRatio);
AddBinding("VideoFilter", cboFilter);
AddBinding("ScreenRotation", cboScreenRotation);
AddBinding("OverscanLeft", nudOverscanLeft);
AddBinding("OverscanRight", nudOverscanRight);
AddBinding("OverscanTop", nudOverscanTop);

View file

@ -166,6 +166,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetPpuNmiConfig(UInt32 extraScanlinesBeforeNmi, UInt32 extraScanlineAfterNmi);
[DllImport(DLLPath)] public static extern void SetOverscanDimensions(UInt32 left, UInt32 right, UInt32 top, UInt32 bottom);
[DllImport(DLLPath)] public static extern void SetVideoScale(double scale);
[DllImport(DLLPath)] public static extern void SetScreenRotation(UInt32 angle);
[DllImport(DLLPath)] public static extern void SetVideoAspectRatio(VideoAspectRatio aspectRatio, double customRatio);
[DllImport(DLLPath)] public static extern void SetVideoFilter(VideoFilterType filter);
[DllImport(DLLPath)] public static extern void SetVideoResizeFilter(VideoResizeFilter filter);
@ -1777,6 +1778,14 @@ namespace Mesen.GUI
Custom = 6
}
public enum ScreenRotation
{
None = 0,
_90Degrees = 90,
_180Degrees = 180,
_270Degrees = 270
}
public enum DebugMemoryType
{
CpuMemory = 0,

View file

@ -431,6 +431,7 @@ namespace InteropEmu {
DllExport void __stdcall SetOverclockRate(uint32_t overclockRate, bool adjustApu) { EmulationSettings::SetOverclockRate(overclockRate, adjustApu); }
DllExport void __stdcall SetPpuNmiConfig(uint32_t extraScanlinesBeforeNmi, uint32_t extraScanlinesAfterNmi) { EmulationSettings::SetPpuNmiConfig(extraScanlinesBeforeNmi, extraScanlinesAfterNmi); }
DllExport void __stdcall SetVideoScale(double scale) { EmulationSettings::SetVideoScale(scale); }
DllExport void __stdcall SetScreenRotation(uint32_t angle) { EmulationSettings::SetScreenRotation(angle); }
DllExport void __stdcall SetVideoAspectRatio(VideoAspectRatio aspectRatio, double customRatio) { EmulationSettings::SetVideoAspectRatio(aspectRatio, customRatio); }
DllExport void __stdcall SetVideoFilter(VideoFilterType filter) { EmulationSettings::SetVideoFilterType(filter); }
DllExport void __stdcall SetVideoResizeFilter(VideoResizeFilter filter) { EmulationSettings::SetVideoResizeFilter(filter); }