PPU: Always output a 239-line picture (+ UI refactoring for scaling/resizing logic)
This commit is contained in:
parent
a8d388043e
commit
61c1b58051
6 changed files with 129 additions and 80 deletions
17
Core/Ppu.cpp
17
Core/Ppu.cpp
|
@ -22,8 +22,8 @@ Ppu::Ppu(shared_ptr<Console> console)
|
|||
|
||||
_outputBuffers[0] = new uint16_t[512 * 478];
|
||||
_outputBuffers[1] = new uint16_t[512 * 478];
|
||||
memset(_outputBuffers[0], 0, 512 * 478);
|
||||
memset(_outputBuffers[1], 0, 512 * 478);
|
||||
memset(_outputBuffers[0], 0, 512 * 478 * sizeof(uint16_t));
|
||||
memset(_outputBuffers[1], 0, 512 * 478 * sizeof(uint16_t));
|
||||
|
||||
_currentBuffer = _outputBuffers[0];
|
||||
|
||||
|
@ -1016,7 +1016,8 @@ void Ppu::ApplyBrightness()
|
|||
|
||||
void Ppu::ApplyHiResMode()
|
||||
{
|
||||
uint16_t scanline = _scanline - 1;
|
||||
//When overscan mode is off, center the 224-line picture in the center of the 239-line output buffer
|
||||
uint16_t scanline = _overscanMode ? (_scanline - 1) : (_scanline + 7);
|
||||
uint32_t screenY = IsDoubleHeight() ? ((_frameCount & 0x01) ? ((scanline << 1) + 1) : (scanline << 1)) : (scanline << 1);
|
||||
uint32_t baseAddr = (screenY << 9);
|
||||
|
||||
|
@ -1073,10 +1074,16 @@ void Ppu::ProcessWindowMaskSettings(uint8_t value, uint8_t offset)
|
|||
|
||||
void Ppu::SendFrame()
|
||||
{
|
||||
constexpr uint16_t width = 512;
|
||||
constexpr uint16_t height = 478;
|
||||
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::PpuFrameDone);
|
||||
|
||||
uint16_t width = 512;
|
||||
uint16_t height = _overscanMode ? 478 : 448;
|
||||
if(!_overscanMode) {
|
||||
//Clear the top 7 and bottom 8 rows
|
||||
memset(_currentBuffer, 0, width * 14 * sizeof(uint16_t));
|
||||
memset(_currentBuffer + width * 462, 0, width * 16 * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
bool isRewinding = _console->GetRewindManager()->IsRewinding();
|
||||
if(isRewinding || _screenInterlace) {
|
||||
|
|
|
@ -28,7 +28,7 @@ private:
|
|||
atomic<bool> _stopFlag;
|
||||
uint32_t _frameCount = 0;
|
||||
|
||||
FrameInfo _baseFrameInfo = { 256, 224 };
|
||||
FrameInfo _baseFrameInfo = { 512, 478 };
|
||||
ScreenSize _previousScreenSize = {};
|
||||
double _previousScale = 0;
|
||||
FrameInfo _lastFrameInfo;
|
||||
|
|
87
UI/Emulation/DisplayManager.cs
Normal file
87
UI/Emulation/DisplayManager.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Emulation
|
||||
{
|
||||
public class DisplayManager
|
||||
{
|
||||
private frmMain _frm;
|
||||
private ctrlRenderer _renderer;
|
||||
private Panel _panel;
|
||||
|
||||
public DisplayManager(frmMain frm, ctrlRenderer renderer, Panel panel)
|
||||
{
|
||||
_frm = frm;
|
||||
_renderer = renderer;
|
||||
_panel = panel;
|
||||
_frm.Resize += frmMain_Resize;
|
||||
}
|
||||
|
||||
private void frmMain_Resize(object sender, EventArgs e)
|
||||
{
|
||||
SetScaleBasedOnWindowSize();
|
||||
}
|
||||
|
||||
public void UpdateViewerSize(bool resizeForm)
|
||||
{
|
||||
ScreenSize screenSize = EmuApi.GetScreenSize(false);
|
||||
|
||||
if(resizeForm && _frm.WindowState != FormWindowState.Maximized) {
|
||||
_frm.Resize -= frmMain_Resize;
|
||||
Size newSize = new Size(screenSize.Width, screenSize.Height);
|
||||
_frm.ClientSize = new Size(newSize.Width, newSize.Height + _panel.Top);
|
||||
_frm.Resize += frmMain_Resize;
|
||||
}
|
||||
|
||||
_renderer.Size = new Size(screenSize.Width, screenSize.Height);
|
||||
_renderer.Top = (_panel.Height - _renderer.Height) / 2;
|
||||
_renderer.Left = (_panel.Width - _renderer.Width) / 2;
|
||||
}
|
||||
|
||||
public void SetScaleBasedOnDimensions(Size dimensions)
|
||||
{
|
||||
ScreenSize size = EmuApi.GetScreenSize(true);
|
||||
|
||||
double verticalScale = (double)dimensions.Height / size.Height;
|
||||
double horizontalScale = (double)dimensions.Width / size.Width;
|
||||
double scale = Math.Min(verticalScale, horizontalScale);
|
||||
/*if(_fullscreenMode && ConfigManager.Config.Video.FullscreenForceIntegerScale) {
|
||||
scale = Math.Floor(scale);
|
||||
}*/
|
||||
|
||||
SetScale(scale, false);
|
||||
}
|
||||
|
||||
private void SetScaleBasedOnWindowSize()
|
||||
{
|
||||
SetScaleBasedOnDimensions(_panel.ClientSize);
|
||||
}
|
||||
|
||||
private void SetScaleBasedOnScreenSize()
|
||||
{
|
||||
SetScaleBasedOnDimensions(Screen.FromControl(_frm).Bounds.Size);
|
||||
}
|
||||
|
||||
public void SetScale(double scale, bool resizeForm)
|
||||
{
|
||||
ConfigManager.Config.Video.VideoScale = scale;
|
||||
ConfigManager.Config.Video.ApplyConfig();
|
||||
ConfigManager.ApplyChanges();
|
||||
|
||||
UpdateViewerSize(resizeForm);
|
||||
}
|
||||
|
||||
public void ToggleFullscreen()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,10 +13,14 @@ namespace Mesen.GUI.Emulation
|
|||
{
|
||||
public class ShortcutHandler
|
||||
{
|
||||
private DisplayManager _displayManager;
|
||||
private Dictionary<EmulatorShortcut, Func<bool>> _actionEnabledFuncs = new Dictionary<EmulatorShortcut, Func<bool>>();
|
||||
private List<uint> _speedValues = new List<uint> { 1, 3, 6, 12, 25, 50, 75, 100, 150, 200, 250, 300, 350, 400, 450, 500, 750, 1000, 2000, 4000 };
|
||||
|
||||
public bool AutoResizeForm { get; internal set; }
|
||||
public ShortcutHandler(DisplayManager displayManager)
|
||||
{
|
||||
_displayManager = displayManager;
|
||||
}
|
||||
|
||||
public void BindShortcut(ToolStripMenuItem item, EmulatorShortcut shortcut, Func<bool> isActionEnabled = null)
|
||||
{
|
||||
|
@ -80,18 +84,18 @@ namespace Mesen.GUI.Emulation
|
|||
case EmulatorShortcut.ToggleAlwaysOnTop: ToggleAlwaysOnTop(); break;
|
||||
case EmulatorShortcut.ToggleDebugInfo: ToggleDebugInfo(); break;
|
||||
case EmulatorShortcut.MaxSpeed: ToggleMaxSpeed(); break;
|
||||
//case EmulatorShortcut.ToggleFullscreen: ToggleFullscreen(); restoreFullscreen = false; break;
|
||||
case EmulatorShortcut.ToggleFullscreen: _displayManager.ToggleFullscreen(); break;
|
||||
|
||||
case EmulatorShortcut.OpenFile: OpenFile(); break;
|
||||
case EmulatorShortcut.IncreaseSpeed: IncreaseEmulationSpeed(); break;
|
||||
case EmulatorShortcut.DecreaseSpeed: DecreaseEmulationSpeed(); break;
|
||||
|
||||
case EmulatorShortcut.SetScale1x: SetScale(1); break;
|
||||
case EmulatorShortcut.SetScale2x: SetScale(2); break;
|
||||
case EmulatorShortcut.SetScale3x: SetScale(3); break;
|
||||
case EmulatorShortcut.SetScale4x: SetScale(4); break;
|
||||
case EmulatorShortcut.SetScale5x: SetScale(5); break;
|
||||
case EmulatorShortcut.SetScale6x: SetScale(6); break;
|
||||
case EmulatorShortcut.SetScale1x: _displayManager.SetScale(1, true); break;
|
||||
case EmulatorShortcut.SetScale2x: _displayManager.SetScale(2, true); break;
|
||||
case EmulatorShortcut.SetScale3x: _displayManager.SetScale(3, true); break;
|
||||
case EmulatorShortcut.SetScale4x: _displayManager.SetScale(4, true); break;
|
||||
case EmulatorShortcut.SetScale5x: _displayManager.SetScale(5, true); break;
|
||||
case EmulatorShortcut.SetScale6x: _displayManager.SetScale(6, true); break;
|
||||
|
||||
case EmulatorShortcut.TakeScreenshot: EmuApi.TakeScreenshot(); break;
|
||||
|
||||
|
@ -145,7 +149,7 @@ namespace Mesen.GUI.Emulation
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetRegion(ConsoleRegion region)
|
||||
{
|
||||
ConfigManager.Config.Emulation.Region = region;
|
||||
|
@ -160,14 +164,6 @@ namespace Mesen.GUI.Emulation
|
|||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
public void SetScale(double scale, bool autoResize = true)
|
||||
{
|
||||
this.AutoResizeForm = autoResize;
|
||||
ConfigManager.Config.Video.VideoScale = scale;
|
||||
ConfigManager.Config.Video.ApplyConfig();
|
||||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
public void ToggleBilinearInterpolation()
|
||||
{
|
||||
ConfigManager.Config.Video.UseBilinearInterpolation = !ConfigManager.Config.Video.UseBilinearInterpolation;
|
||||
|
@ -229,7 +225,9 @@ namespace Mesen.GUI.Emulation
|
|||
|
||||
private void ToggleOsd()
|
||||
{
|
||||
//TODO
|
||||
ConfigManager.Config.Preferences.DisableOsd = !ConfigManager.Config.Preferences.DisableOsd;
|
||||
ConfigManager.Config.Preferences.ApplyConfig();
|
||||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
private void ToggleFps()
|
||||
|
|
|
@ -22,10 +22,15 @@ namespace Mesen.GUI.Forms
|
|||
{
|
||||
private NotificationListener _notifListener;
|
||||
private ShortcutHandler _shortcuts;
|
||||
private DisplayManager _displayManager;
|
||||
|
||||
public frmMain(string[] args)
|
||||
{
|
||||
InitializeComponent();
|
||||
if(DesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceHelper.LoadResources(Language.English);
|
||||
}
|
||||
|
||||
|
@ -44,8 +49,6 @@ namespace Mesen.GUI.Forms
|
|||
{
|
||||
base.OnShown(e);
|
||||
|
||||
_shortcuts = new ShortcutHandler();
|
||||
|
||||
EmuApi.InitDll();
|
||||
ConfigManager.Config.Video.ApplyConfig();
|
||||
EmuApi.InitializeEmu(ConfigManager.HomeFolder, Handle, ctrlRenderer.Handle, false, false, false);
|
||||
|
@ -53,9 +56,13 @@ namespace Mesen.GUI.Forms
|
|||
ConfigManager.Config.InitializeDefaults();
|
||||
ConfigManager.Config.ApplyConfig();
|
||||
|
||||
_displayManager = new DisplayManager(this, ctrlRenderer, pnlRenderer);
|
||||
_displayManager.UpdateViewerSize(false);
|
||||
_shortcuts = new ShortcutHandler(_displayManager);
|
||||
|
||||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
|
||||
|
||||
SaveStateManager.InitializeStateMenu(mnuSaveState, true, _shortcuts);
|
||||
SaveStateManager.InitializeStateMenu(mnuLoadState, false, _shortcuts);
|
||||
|
||||
|
@ -63,9 +70,9 @@ namespace Mesen.GUI.Forms
|
|||
|
||||
ctrlRecentGames.Initialize();
|
||||
ctrlRecentGames.Visible = true;
|
||||
ResizeRecentGames();
|
||||
|
||||
this.Resize += frmMain_Resize;
|
||||
ResizeRecentGames();
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
|
@ -105,13 +112,6 @@ namespace Mesen.GUI.Forms
|
|||
}));
|
||||
break;
|
||||
|
||||
case ConsoleNotificationType.ResolutionChanged:
|
||||
ScreenSize size = EmuApi.GetScreenSize(false);
|
||||
this.BeginInvoke((Action)(() => {
|
||||
UpdateViewerSize(size);
|
||||
}));
|
||||
break;
|
||||
|
||||
case ConsoleNotificationType.ExecuteShortcut:
|
||||
this.BeginInvoke((Action)(() => {
|
||||
_shortcuts.ExecuteShortcut((EmulatorShortcut)e.Parameter);
|
||||
|
@ -191,58 +191,14 @@ namespace Mesen.GUI.Forms
|
|||
mnuRegionPal.Click += (s, e) => { _shortcuts.SetRegion(ConsoleRegion.Pal); };
|
||||
}
|
||||
|
||||
private void UpdateViewerSize(ScreenSize screenSize)
|
||||
{
|
||||
if(_shortcuts.AutoResizeForm && this.WindowState != FormWindowState.Maximized) {
|
||||
this.Resize -= frmMain_Resize;
|
||||
Size newSize = new Size(screenSize.Width, screenSize.Height);
|
||||
this.ClientSize = new Size(newSize.Width, newSize.Height + pnlRenderer.Top);
|
||||
this.Resize += frmMain_Resize;
|
||||
}
|
||||
|
||||
ctrlRenderer.Size = new Size(screenSize.Width, screenSize.Height);
|
||||
ctrlRenderer.Top = (pnlRenderer.Height - ctrlRenderer.Height) / 2;
|
||||
ctrlRenderer.Left = (pnlRenderer.Width - ctrlRenderer.Width) / 2;
|
||||
}
|
||||
|
||||
private void SetScaleBasedOnDimensions(Size dimensions)
|
||||
{
|
||||
ScreenSize size = EmuApi.GetScreenSize(true);
|
||||
|
||||
double verticalScale = (double)dimensions.Height / size.Height;
|
||||
double horizontalScale = (double)dimensions.Width / size.Width;
|
||||
double scale = Math.Min(verticalScale, horizontalScale);
|
||||
/*if(_fullscreenMode && ConfigManager.Config.Video.FullscreenForceIntegerScale) {
|
||||
scale = Math.Floor(scale);
|
||||
}*/
|
||||
|
||||
_shortcuts.SetScale(scale, false);
|
||||
}
|
||||
|
||||
private void SetScaleBasedOnWindowSize()
|
||||
{
|
||||
SetScaleBasedOnDimensions(pnlRenderer.ClientSize);
|
||||
}
|
||||
|
||||
private void SetScaleBasedOnScreenSize()
|
||||
{
|
||||
SetScaleBasedOnDimensions(Screen.FromControl(this).Bounds.Size);
|
||||
}
|
||||
|
||||
private void ResizeRecentGames()
|
||||
{
|
||||
ctrlRecentGames.Height = this.ClientSize.Height - ctrlRecentGames.Top - 80;
|
||||
}
|
||||
|
||||
private void ProcessResize()
|
||||
{
|
||||
ResizeRecentGames();
|
||||
SetScaleBasedOnWindowSize();
|
||||
}
|
||||
|
||||
private void frmMain_Resize(object sender, EventArgs e)
|
||||
{
|
||||
ProcessResize();
|
||||
ResizeRecentGames();
|
||||
}
|
||||
|
||||
private void mnuVideoConfig_Click(object sender, EventArgs e)
|
||||
|
|
|
@ -467,6 +467,7 @@
|
|||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\WatchManager.cs" />
|
||||
<Compile Include="Emulation\DisplayManager.cs" />
|
||||
<Compile Include="Emulation\SaveStateManager.cs" />
|
||||
<Compile Include="Forms\BaseConfigForm.Designer.cs">
|
||||
<DependentUpon>BaseConfigForm.cs</DependentUpon>
|
||||
|
|
Loading…
Add table
Reference in a new issue