Video: Added customizable RGB palette

This commit is contained in:
Souryo 2016-01-17 14:21:31 -05:00
parent df369722d1
commit 117a4b073d
13 changed files with 288 additions and 76 deletions

View file

@ -2,8 +2,6 @@
#include "DefaultVideoFilter.h"
#include "EmulationSettings.h"
extern const uint32_t PPU_PALETTE_ARGB[];
FrameInfo DefaultVideoFilter::GetFrameInfo()
{
OverscanDimensions overscan = GetOverscan();
@ -25,7 +23,7 @@ void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel)
{
uint32_t pixelOutput = PPU_PALETTE_ARGB[ppuPixel & 0x3F];
uint32_t pixelOutput = EmulationSettings::GetRgbPalette()[ppuPixel & 0x3F];
//Incorrect emphasis bit implementation, but will do for now.
float redChannel = (float)((pixelOutput & 0xFF0000) >> 16);

View file

@ -1,6 +1,22 @@
#include "stdafx.h"
#include "EmulationSettings.h"
uint32_t EmulationSettings::PpuPaletteArgb[64] = {
0xFF666666, 0xFF002A88, 0xFF1412A7, 0xFF3B00A4, 0xFF5C007E,
0xFF6E0040, 0xFF6C0600, 0xFF561D00, 0xFF333500, 0xFF0B4800,
0xFF005200, 0xFF004F08, 0xFF00404D, 0xFF000000, 0xFF000000,
0xFF000000, 0xFFADADAD, 0xFF155FD9, 0xFF4240FF, 0xFF7527FE,
0xFFA01ACC, 0xFFB71E7B, 0xFFB53120, 0xFF994E00, 0xFF6B6D00,
0xFF388700, 0xFF0C9300, 0xFF008F32, 0xFF007C8D, 0xFF000000,
0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFF64B0FF, 0xFF9290FF,
0xFFC676FF, 0xFFF36AFF, 0xFFFE6ECC, 0xFFFE8170, 0xFFEA9E22,
0xFFBCBE00, 0xFF88D800, 0xFF5CE430, 0xFF45E082, 0xFF48CDDE,
0xFF4F4F4F, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFFC0DFFF,
0xFFD3D2FF, 0xFFE8C8FF, 0xFFFBC2FF, 0xFFFEC4EA, 0xFFFECCC5,
0xFFF7D8A5, 0xFFE4E594, 0xFFCFEF96, 0xFFBDF4AB, 0xFFB3F3CC,
0xFFB5EBF2, 0xFFB8B8B8, 0xFF000000, 0xFF000000,
};
uint32_t EmulationSettings::_flags = 0;
uint32_t EmulationSettings::_audioLatency = 20000;

View file

@ -64,6 +64,7 @@ struct OverscanDimensions
class EmulationSettings
{
private:
static uint32_t PpuPaletteArgb[64];
static uint32_t _flags;
static uint32_t _audioLatency;
@ -201,4 +202,19 @@ public:
{
return _videoScale;
}
static uint32_t* GetRgbPalette()
{
return PpuPaletteArgb;
}
static void GetRgbPalette(uint32_t* paletteBuffer)
{
memcpy(paletteBuffer, PpuPaletteArgb, sizeof(PpuPaletteArgb));
}
static void SetRgbPalette(uint32_t* paletteBuffer)
{
memcpy(PpuPaletteArgb, paletteBuffer, sizeof(PpuPaletteArgb));
}
};

View file

@ -7,8 +7,6 @@
#include "../Utilities/FolderUtilities.h"
#include "../Utilities/PNGHelper.h"
extern const uint32_t PPU_PALETTE_ARGB[];
struct HdPpuTileInfo
{
static const uint32_t NoTile = -1;
@ -184,7 +182,7 @@ public:
for(uint32_t y = 0; y < _hdScale; y++) {
for(uint32_t x = 0; x < _hdScale; x++) {
if(drawBackground) {
*outputBuffer = PPU_PALETTE_ARGB[tileInfo.BgColor];
*outputBuffer = EmulationSettings::GetRgbPalette()[tileInfo.BgColor];
}
if(!tileInfo.BackgroundPriority || tileInfo.BgColorIndex == 0) {
if((bitmapData[bitmapOffset] & 0xFF000000) == 0xFF000000) {

View file

@ -2,8 +2,6 @@
#include "HdNesPack.h"
#include "HdVideoFilter.h"
extern const uint32_t PPU_PALETTE_ARGB[];
HdVideoFilter::HdVideoFilter()
{
_hdNesPack.reset(new HdNesPack());
@ -31,7 +29,7 @@ void HdVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
for(uint32_t i = overscan.Top, iMax = 240 - overscan.Bottom; i < iMax; i++) {
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
uint32_t sdPixel = PPU_PALETTE_ARGB[ppuOutputBuffer[i * 256 + j] & 0x3F]; //ProcessIntensifyBits(inputBuffer[i * 256 + j]);
uint32_t sdPixel = EmulationSettings::GetRgbPalette()[ppuOutputBuffer[i * 256 + j] & 0x3F]; //ProcessIntensifyBits(inputBuffer[i * 256 + j]);
uint32_t bufferIndex = (i - overscan.Top) * screenWidth * hdScale + (j - overscan.Left) * hdScale;
_hdNesPack->GetPixels(_hdScreenTiles[i * 256 + j], sdPixel, (uint32_t*)GetOutputBuffer() + bufferIndex, screenWidth);
}

View file

@ -6,22 +6,6 @@
#include "NtscFilter.h"
#include "HdVideoFilter.h"
const uint32_t PPU_PALETTE_ARGB[64] = {
0xFF666666, 0xFF002A88, 0xFF1412A7, 0xFF3B00A4, 0xFF5C007E,
0xFF6E0040, 0xFF6C0600, 0xFF561D00, 0xFF333500, 0xFF0B4800,
0xFF005200, 0xFF004F08, 0xFF00404D, 0xFF000000, 0xFF000000,
0xFF000000, 0xFFADADAD, 0xFF155FD9, 0xFF4240FF, 0xFF7527FE,
0xFFA01ACC, 0xFFB71E7B, 0xFFB53120, 0xFF994E00, 0xFF6B6D00,
0xFF388700, 0xFF0C9300, 0xFF008F32, 0xFF007C8D, 0xFF000000,
0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFF64B0FF, 0xFF9290FF,
0xFFC676FF, 0xFFF36AFF, 0xFFFE6ECC, 0xFFFE8170, 0xFFEA9E22,
0xFFBCBE00, 0xFF88D800, 0xFF5CE430, 0xFF45E082, 0xFF48CDDE,
0xFF4F4F4F, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFFC0DFFF,
0xFFD3D2FF, 0xFFE8C8FF, 0xFFFBC2FF, 0xFFFEC4EA, 0xFFFECCC5,
0xFFF7D8A5, 0xFFE4E594, 0xFFCFEF96, 0xFFBDF4AB, 0xFFB3F3CC,
0xFFB5EBF2, 0xFFB8B8B8, 0xFF000000, 0xFF000000,
};
unique_ptr<VideoDecoder> VideoDecoder::Instance;
VideoDecoder* VideoDecoder::GetInstance()
@ -87,7 +71,7 @@ void VideoDecoder::DecodeFrame()
void VideoDecoder::DebugDecodeFrame(uint16_t* inputBuffer, uint32_t* outputBuffer, uint32_t length)
{
for(uint32_t i = 0; i < length; i++) {
outputBuffer[i] = PPU_PALETTE_ARGB[inputBuffer[i] & 0x3F];
outputBuffer[i] = EmulationSettings::GetRgbPalette()[inputBuffer[i] & 0x3F];
}
}

View file

@ -12,18 +12,18 @@ namespace Mesen.GUI.Config
{
private const int MaxRecentFiles = 10;
public PlayerProfile Profile;
public ClientConnectionInfo ClientConnectionInfo;
public ServerInfo ServerInfo;
public PreferenceInfo PreferenceInfo;
public AudioInfo AudioInfo;
public VideoInfo VideoInfo;
public PreferenceInfo PreferenceInfo;
public List<string> RecentFiles;
public List<CheatInfo> Cheats;
public List<ControllerInfo> Controllers;
public bool ShowOnlyCheatsForCurrentGame;
public bool AutoLoadIpsPatches;
public NesModel Region;
public ClientConnectionInfo ClientConnectionInfo;
public ServerInfo ServerInfo;
public PlayerProfile Profile;
public Configuration()
{

View file

@ -23,6 +23,7 @@ namespace Mesen.GUI.Config
public bool VerticalSync = true;
public bool FullscreenMode = false;
public bool UseHdPacks = false;
public Int32[] Palette = new Int32[0];
public VideoInfo()
{
@ -42,6 +43,10 @@ namespace Mesen.GUI.Config
InteropEmu.SetVideoFilter(videoInfo.VideoFilter);
InteropEmu.SetVideoScale(videoInfo.VideoScale);
if(videoInfo.Palette.Length == 64) {
InteropEmu.SetRgbPalette(videoInfo.Palette);
}
}
}
}

View file

@ -41,6 +41,9 @@
this.lblEmuSpeedHint = new System.Windows.Forms.Label();
this.lblEmulationSpeed = new System.Windows.Forms.Label();
this.chkShowFps = new System.Windows.Forms.CheckBox();
this.flowLayoutPanel7 = new System.Windows.Forms.FlowLayoutPanel();
this.chkUseHdPacks = new System.Windows.Forms.CheckBox();
this.picHdNesTooltip = new System.Windows.Forms.PictureBox();
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgGeneral = new System.Windows.Forms.TabPage();
this.tpgOverscan = new System.Windows.Forms.TabPage();
@ -60,12 +63,17 @@
this.lblRight = new System.Windows.Forms.Label();
this.nudOverscanRight = new System.Windows.Forms.NumericUpDown();
this.tpgPalette = new System.Windows.Forms.TabPage();
this.chkUseHdPacks = new System.Windows.Forms.CheckBox();
this.flowLayoutPanel7 = new System.Windows.Forms.FlowLayoutPanel();
this.picHdNesTooltip = new System.Windows.Forms.PictureBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.picPalette = new System.Windows.Forms.PictureBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.btnResetPalette = new System.Windows.Forms.Button();
this.btnLoadPalFile = new System.Windows.Forms.Button();
this.colorDialog = new System.Windows.Forms.ColorDialog();
this.tlpMain.SuspendLayout();
this.flowLayoutPanel6.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudEmulationSpeed)).BeginInit();
this.flowLayoutPanel7.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picHdNesTooltip)).BeginInit();
this.tabMain.SuspendLayout();
this.tpgGeneral.SuspendLayout();
this.tpgOverscan.SuspendLayout();
@ -80,14 +88,16 @@
((System.ComponentModel.ISupportInitialize)(this.nudOverscanBottom)).BeginInit();
this.flowLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).BeginInit();
this.flowLayoutPanel7.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picHdNesTooltip)).BeginInit();
this.tpgPalette.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picPalette)).BeginInit();
this.tableLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 308);
this.baseConfigPanel.Size = new System.Drawing.Size(362, 29);
this.baseConfigPanel.Location = new System.Drawing.Point(0, 288);
this.baseConfigPanel.Size = new System.Drawing.Size(515, 29);
//
// tlpMain
//
@ -120,7 +130,7 @@
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.Size = new System.Drawing.Size(348, 276);
this.tlpMain.Size = new System.Drawing.Size(501, 256);
this.tlpMain.TabIndex = 1;
//
// chkFullscreenMode
@ -227,7 +237,7 @@
this.flowLayoutPanel6.Location = new System.Drawing.Point(96, 173);
this.flowLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel6.Name = "flowLayoutPanel6";
this.flowLayoutPanel6.Size = new System.Drawing.Size(252, 26);
this.flowLayoutPanel6.Size = new System.Drawing.Size(405, 26);
this.flowLayoutPanel6.TabIndex = 10;
//
// nudEmulationSpeed
@ -274,6 +284,37 @@
this.chkShowFps.Text = "Show FPS";
this.chkShowFps.UseVisualStyleBackColor = true;
//
// flowLayoutPanel7
//
this.tlpMain.SetColumnSpan(this.flowLayoutPanel7, 2);
this.flowLayoutPanel7.Controls.Add(this.chkUseHdPacks);
this.flowLayoutPanel7.Controls.Add(this.picHdNesTooltip);
this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 81);
this.flowLayoutPanel7.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel7.Name = "flowLayoutPanel7";
this.flowLayoutPanel7.Size = new System.Drawing.Size(166, 23);
this.flowLayoutPanel7.TabIndex = 20;
//
// chkUseHdPacks
//
this.chkUseHdPacks.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkUseHdPacks.AutoSize = true;
this.chkUseHdPacks.Location = new System.Drawing.Point(3, 3);
this.chkUseHdPacks.Name = "chkUseHdPacks";
this.chkUseHdPacks.Size = new System.Drawing.Size(134, 17);
this.chkUseHdPacks.TabIndex = 19;
this.chkUseHdPacks.Text = "Use HDNes HD packs";
this.chkUseHdPacks.UseVisualStyleBackColor = true;
//
// picHdNesTooltip
//
this.picHdNesTooltip.Image = global::Mesen.GUI.Properties.Resources.help;
this.picHdNesTooltip.Location = new System.Drawing.Point(143, 3);
this.picHdNesTooltip.Name = "picHdNesTooltip";
this.picHdNesTooltip.Size = new System.Drawing.Size(17, 17);
this.picHdNesTooltip.TabIndex = 21;
this.picHdNesTooltip.TabStop = false;
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgGeneral);
@ -283,7 +324,7 @@
this.tabMain.Location = new System.Drawing.Point(0, 0);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(362, 308);
this.tabMain.Size = new System.Drawing.Size(515, 288);
this.tabMain.TabIndex = 2;
//
// tpgGeneral
@ -292,7 +333,7 @@
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(354, 282);
this.tpgGeneral.Size = new System.Drawing.Size(507, 262);
this.tpgGeneral.TabIndex = 0;
this.tpgGeneral.Text = "General";
this.tpgGeneral.UseVisualStyleBackColor = true;
@ -303,7 +344,7 @@
this.tpgOverscan.Location = new System.Drawing.Point(4, 22);
this.tpgOverscan.Name = "tpgOverscan";
this.tpgOverscan.Padding = new System.Windows.Forms.Padding(3);
this.tpgOverscan.Size = new System.Drawing.Size(354, 282);
this.tpgOverscan.Size = new System.Drawing.Size(507, 262);
this.tpgOverscan.TabIndex = 1;
this.tpgOverscan.Text = "Overscan";
this.tpgOverscan.UseVisualStyleBackColor = true;
@ -314,7 +355,7 @@
this.grpCropping.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpCropping.Location = new System.Drawing.Point(3, 3);
this.grpCropping.Name = "grpCropping";
this.grpCropping.Size = new System.Drawing.Size(348, 276);
this.grpCropping.Size = new System.Drawing.Size(501, 256);
this.grpCropping.TabIndex = 8;
this.grpCropping.TabStop = false;
this.grpCropping.Text = "Video Cropping";
@ -470,50 +511,88 @@
//
// tpgPalette
//
this.tpgPalette.Controls.Add(this.tableLayoutPanel3);
this.tpgPalette.Location = new System.Drawing.Point(4, 22);
this.tpgPalette.Name = "tpgPalette";
this.tpgPalette.Padding = new System.Windows.Forms.Padding(3);
this.tpgPalette.Size = new System.Drawing.Size(354, 282);
this.tpgPalette.Size = new System.Drawing.Size(507, 262);
this.tpgPalette.TabIndex = 2;
this.tpgPalette.Text = "Palette";
this.tpgPalette.UseVisualStyleBackColor = true;
//
// chkUseHdPacks
// tableLayoutPanel3
//
this.chkUseHdPacks.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkUseHdPacks.AutoSize = true;
this.chkUseHdPacks.Location = new System.Drawing.Point(3, 3);
this.chkUseHdPacks.Name = "chkUseHdPacks";
this.chkUseHdPacks.Size = new System.Drawing.Size(134, 17);
this.chkUseHdPacks.TabIndex = 19;
this.chkUseHdPacks.Text = "Use HDNes HD packs";
this.chkUseHdPacks.UseVisualStyleBackColor = true;
this.tableLayoutPanel3.ColumnCount = 2;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel3.Controls.Add(this.picPalette, 0, 1);
this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel2, 1, 1);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 2;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.Size = new System.Drawing.Size(501, 256);
this.tableLayoutPanel3.TabIndex = 4;
//
// flowLayoutPanel7
// picPalette
//
this.tlpMain.SetColumnSpan(this.flowLayoutPanel7, 2);
this.flowLayoutPanel7.Controls.Add(this.chkUseHdPacks);
this.flowLayoutPanel7.Controls.Add(this.picHdNesTooltip);
this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 81);
this.flowLayoutPanel7.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.flowLayoutPanel7.Name = "flowLayoutPanel7";
this.flowLayoutPanel7.Size = new System.Drawing.Size(166, 23);
this.flowLayoutPanel7.TabIndex = 20;
this.picPalette.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picPalette.Cursor = System.Windows.Forms.Cursors.Hand;
this.picPalette.Location = new System.Drawing.Point(1, 1);
this.picPalette.Margin = new System.Windows.Forms.Padding(1);
this.picPalette.Name = "picPalette";
this.picPalette.Size = new System.Drawing.Size(386, 98);
this.picPalette.TabIndex = 0;
this.picPalette.TabStop = false;
this.picPalette.MouseDown += new System.Windows.Forms.MouseEventHandler(this.picPalette_MouseDown);
//
// picHdNesTooltip
// tableLayoutPanel2
//
this.picHdNesTooltip.Image = global::Mesen.GUI.Properties.Resources.help;
this.picHdNesTooltip.Location = new System.Drawing.Point(143, 3);
this.picHdNesTooltip.Name = "picHdNesTooltip";
this.picHdNesTooltip.Size = new System.Drawing.Size(17, 17);
this.picHdNesTooltip.TabIndex = 21;
this.picHdNesTooltip.TabStop = false;
this.tableLayoutPanel2.ColumnCount = 1;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Controls.Add(this.btnResetPalette, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.btnLoadPalFile, 0, 0);
this.tableLayoutPanel2.Location = new System.Drawing.Point(388, 0);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 3;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(113, 73);
this.tableLayoutPanel2.TabIndex = 1;
//
// btnResetPalette
//
this.btnResetPalette.Location = new System.Drawing.Point(3, 31);
this.btnResetPalette.Name = "btnResetPalette";
this.btnResetPalette.Size = new System.Drawing.Size(106, 22);
this.btnResetPalette.TabIndex = 1;
this.btnResetPalette.Text = "Reset to Defaults";
this.btnResetPalette.UseVisualStyleBackColor = true;
this.btnResetPalette.Click += new System.EventHandler(this.btnResetPalette_Click);
//
// btnLoadPalFile
//
this.btnLoadPalFile.Location = new System.Drawing.Point(3, 3);
this.btnLoadPalFile.Name = "btnLoadPalFile";
this.btnLoadPalFile.Size = new System.Drawing.Size(106, 22);
this.btnLoadPalFile.TabIndex = 0;
this.btnLoadPalFile.Text = "Load Palette File";
this.btnLoadPalFile.UseVisualStyleBackColor = true;
this.btnLoadPalFile.Click += new System.EventHandler(this.btnLoadPalFile_Click);
//
// frmVideoConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(362, 337);
this.ClientSize = new System.Drawing.Size(515, 317);
this.Controls.Add(this.tabMain);
this.Name = "frmVideoConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
@ -525,6 +604,9 @@
this.flowLayoutPanel6.ResumeLayout(false);
this.flowLayoutPanel6.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudEmulationSpeed)).EndInit();
this.flowLayoutPanel7.ResumeLayout(false);
this.flowLayoutPanel7.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picHdNesTooltip)).EndInit();
this.tabMain.ResumeLayout(false);
this.tpgGeneral.ResumeLayout(false);
this.tpgOverscan.ResumeLayout(false);
@ -543,9 +625,10 @@
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).EndInit();
this.flowLayoutPanel7.ResumeLayout(false);
this.flowLayoutPanel7.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picHdNesTooltip)).EndInit();
this.tpgPalette.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.picPalette)).EndInit();
this.tableLayoutPanel2.ResumeLayout(false);
this.ResumeLayout(false);
}
@ -588,5 +671,11 @@
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel7;
private System.Windows.Forms.CheckBox chkUseHdPacks;
private System.Windows.Forms.PictureBox picHdNesTooltip;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.PictureBox picPalette;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.Button btnResetPalette;
private System.Windows.Forms.Button btnLoadPalFile;
private System.Windows.Forms.ColorDialog colorDialog;
}
}

View file

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -13,6 +15,8 @@ namespace Mesen.GUI.Forms.Config
{
public partial class frmVideoConfig : BaseConfigForm
{
private Int32[] _paletteData;
public frmVideoConfig()
{
InitializeComponent();
@ -34,13 +38,93 @@ namespace Mesen.GUI.Forms.Config
AddBinding("OverscanTop", nudOverscanTop);
AddBinding("OverscanBottom", nudOverscanBottom);
_paletteData = InteropEmu.GetRgbPalette();
RefreshPalette();
toolTip.SetToolTip(picHdNesTooltip, "This option allows Mesen to load HDNes-format HD packs if they are found." + Environment.NewLine + Environment.NewLine + "HD Packs should be placed in the \"HdPacks\" folder in a subfolder matching the name of the ROM." + Environment.NewLine + "e.g: MyRom.nes should have their HD Pack in \"HdPacks\\MyRom\\hires.txt\"." + Environment.NewLine + Environment.NewLine + "Note: Support for HD Packs is a work in progress and some limitations remain.");
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
if(DialogResult == System.Windows.Forms.DialogResult.OK) {
((VideoInfo)Entity).Palette = _paletteData;
}
base.OnFormClosed(e);
VideoInfo.ApplyConfig();
}
private void RefreshPalette()
{
GCHandle handle = GCHandle.Alloc(_paletteData, GCHandleType.Pinned);
try {
Bitmap source = new Bitmap(16, 4, 16*4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
Bitmap target = new Bitmap(384, 96);
using(Graphics g = Graphics.FromImage(target)) {
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
g.DrawImage(source, new Rectangle(0, 0, 384, 96), new Rectangle(0, 0, 16, 4), GraphicsUnit.Pixel);
}
this.picPalette.Image = target;
} finally {
handle.Free();
}
}
private void picPalette_MouseDown(object sender, MouseEventArgs e)
{
int offset = (e.X / 24) + (e.Y / 24 * 16);
colorDialog.SolidColorOnly = true;
colorDialog.AllowFullOpen = true;
colorDialog.FullOpen = true;
colorDialog.Color = Color.FromArgb(_paletteData[offset]);
if(colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
_paletteData[offset] = colorDialog.Color.ToArgb();
}
RefreshPalette();
}
private void btnResetPalette_Click(object sender, EventArgs e)
{
_paletteData = (Int32[])((object)(new UInt32[] {
0xFF666666, 0xFF002A88, 0xFF1412A7, 0xFF3B00A4, 0xFF5C007E,
0xFF6E0040, 0xFF6C0600, 0xFF561D00, 0xFF333500, 0xFF0B4800,
0xFF005200, 0xFF004F08, 0xFF00404D, 0xFF000000, 0xFF000000,
0xFF000000, 0xFFADADAD, 0xFF155FD9, 0xFF4240FF, 0xFF7527FE,
0xFFA01ACC, 0xFFB71E7B, 0xFFB53120, 0xFF994E00, 0xFF6B6D00,
0xFF388700, 0xFF0C9300, 0xFF008F32, 0xFF007C8D, 0xFF000000,
0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFF64B0FF, 0xFF9290FF,
0xFFC676FF, 0xFFF36AFF, 0xFFFE6ECC, 0xFFFE8170, 0xFFEA9E22,
0xFFBCBE00, 0xFF88D800, 0xFF5CE430, 0xFF45E082, 0xFF48CDDE,
0xFF4F4F4F, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFFC0DFFF,
0xFFD3D2FF, 0xFFE8C8FF, 0xFFFBC2FF, 0xFFFEC4EA, 0xFFFECCC5,
0xFFF7D8A5, 0xFFE4E594, 0xFFCFEF96, 0xFFBDF4AB, 0xFFB3F3CC,
0xFFB5EBF2, 0xFFB8B8B8, 0xFF000000, 0xFF000000
}));
RefreshPalette();
}
private void btnLoadPalFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Palette Files (*.pal)|*.pal|All Files (*.*)|*.*";
if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
using(FileStream paletteFile = File.OpenRead(ofd.FileName)) {
byte[] paletteFileData = new byte[64*3];
if(paletteFile.Read(paletteFileData, 0, 64*3) == 64*3) {
for(int i = 0; i < 64; i++) {
int fileOffset = i * 3;
_paletteData[i] = (Int32)((UInt32)0xFF000000 | (UInt32)paletteFileData[fileOffset+2] | (UInt32)(paletteFileData[fileOffset+1] << 8) | (UInt32)(paletteFileData[fileOffset] << 16));
}
RefreshPalette();
}
paletteFile.Close();
}
}
}
}
}

View file

@ -117,4 +117,10 @@
<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="colorDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>
</root>

View file

@ -82,7 +82,9 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetOverscanDimensions(UInt32 left, UInt32 right, UInt32 top, UInt32 bottom);
[DllImport(DLLPath)] public static extern void SetVideoScale(UInt32 scale);
[DllImport(DLLPath)] public static extern void SetVideoFilter(VideoFilterType filter);
[DllImport(DLLPath)] public static extern void SetRgbPalette(Int32[] palette);
[DllImport(DLLPath, EntryPoint="GetRgbPalette")] private static extern void GetRgbPaletteWrapper(IntPtr paletteBuffer);
[DllImport(DLLPath, EntryPoint="GetScreenSize")] private static extern void GetScreenSizeWrapper(out ScreenSize size);
[DllImport(DLLPath)] public static extern void DebugInitialize();
@ -219,6 +221,20 @@ namespace Mesen.GUI
}
}
public static Int32[] GetRgbPalette()
{
Int32[] paleteData = new Int32[64];
GCHandle hPaletteData = GCHandle.Alloc(paleteData, GCHandleType.Pinned);
try {
InteropEmu.GetRgbPaletteWrapper(hPaletteData.AddrOfPinnedObject());
} finally {
hPaletteData.Free();
}
return paleteData;
}
public static string GetROMPath() { return PtrToStringUtf8(InteropEmu.GetROMPathWrapper()); }
public static string GetKeyName(UInt32 key) { return PtrToStringUtf8(InteropEmu.GetKeyNameWrapper(key)); }

View file

@ -217,7 +217,9 @@ namespace InteropEmu {
DllExport void __stdcall SetEmulationSpeed(uint32_t emulationSpeed) { EmulationSettings::SetEmulationSpeed(emulationSpeed); }
DllExport void __stdcall SetVideoScale(uint32_t scale) { EmulationSettings::SetVideoScale(scale); }
DllExport void __stdcall SetVideoFilter(VideoFilterType filter) { EmulationSettings::SetVideoFilterType(filter); }
DllExport void __stdcall GetScreenSize(ScreenSize &size) { VideoDecoder::GetInstance()->GetScreenSize(size); }
DllExport void __stdcall GetRgbPalette(uint32_t *paletteBuffer) { EmulationSettings::GetRgbPalette(paletteBuffer); }
DllExport void __stdcall SetRgbPalette(uint32_t *paletteBuffer) { EmulationSettings::SetRgbPalette(paletteBuffer); }
DllExport void __stdcall GetScreenSize(ScreenSize &size) { VideoDecoder::GetInstance()->GetScreenSize(size); }
}
}