Added support for 512-color palette files

This commit is contained in:
Sour 2019-02-07 18:51:24 -05:00
parent 435c067da1
commit 3a752d6755
11 changed files with 152 additions and 128 deletions

View file

@ -10,8 +10,6 @@
DefaultVideoFilter::DefaultVideoFilter(shared_ptr<Console> console) : BaseVideoFilter(console) DefaultVideoFilter::DefaultVideoFilter(shared_ptr<Console> console) : BaseVideoFilter(console)
{ {
InitDecodeTables();
InitConversionMatrix(_pictureSettings.Hue, _pictureSettings.Saturation); InitConversionMatrix(_pictureSettings.Hue, _pictureSettings.Saturation);
} }
@ -93,53 +91,15 @@ void DefaultVideoFilter::YiqToRgb(double y, double i, double q, double &r, doubl
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)));
} }
void DefaultVideoFilter::InitDecodeTables()
{
for(int i = 0; i < 256; i++) {
for(int j = 0; j < 8; j++) {
double redColor = i;
double greenColor = i;
double blueColor = i;
if(j & 0x01) {
//Intensify red
redColor *= 1.1;
greenColor *= 0.9;
blueColor *= 0.9;
}
if(j & 0x02) {
//Intensify green
greenColor *= 1.1;
redColor *= 0.9;
blueColor *= 0.9;
}
if(j & 0x04) {
//Intensify blue
blueColor *= 1.1;
redColor *= 0.9;
greenColor *= 0.9;
}
redColor = (redColor > 255 ? 255 : redColor) / 255.0;
greenColor = (greenColor > 255 ? 255 : greenColor) / 255.0;
blueColor = (blueColor > 255 ? 255 : blueColor) / 255.0;
_redDecodeTable[i][j] = redColor;
_greenDecodeTable[i][j] = greenColor;
_blueDecodeTable[i][j] = blueColor;
}
}
}
uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel, double scanlineIntensity) uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel, double scanlineIntensity)
{ {
uint32_t pixelOutput = _console->GetSettings()->GetRgbPalette()[ppuPixel & 0x3F]; uint32_t pixelOutput = _console->GetSettings()->GetRgbPalette()[ppuPixel & 0x1FF];
uint32_t intensifyBits = (ppuPixel >> 6) & 0x07;
if(intensifyBits || _needToProcess || scanlineIntensity < 1.0) { if(_needToProcess || scanlineIntensity < 1.0) {
//Incorrect emphasis bit implementation, but will do for now. //Incorrect emphasis bit implementation, but will do for now.
double redChannel = _redDecodeTable[((pixelOutput & 0xFF0000) >> 16)][intensifyBits]; double redChannel = ((pixelOutput & 0xFF0000) >> 16) / 255.0;
double greenChannel = _greenDecodeTable[((pixelOutput & 0xFF00) >> 8)][intensifyBits]; double greenChannel = ((pixelOutput & 0xFF00) >> 8) / 255.0;
double blueChannel = _blueDecodeTable[(pixelOutput & 0xFF)][intensifyBits]; double blueChannel = (pixelOutput & 0xFF) / 255.0;
//Apply brightness, contrast, hue & saturation //Apply brightness, contrast, hue & saturation
if(_needToProcess) { if(_needToProcess) {

View file

@ -6,15 +6,10 @@
class DefaultVideoFilter : public BaseVideoFilter class DefaultVideoFilter : public BaseVideoFilter
{ {
private: private:
double _redDecodeTable[256][8];
double _greenDecodeTable[256][8];
double _blueDecodeTable[256][8];
double _yiqToRgbMatrix[6]; double _yiqToRgbMatrix[6];
PictureSettings _pictureSettings; PictureSettings _pictureSettings;
bool _needToProcess = false; bool _needToProcess = false;
void InitDecodeTables();
void InitConversionMatrix(double hueShift, double saturationShift); void InitConversionMatrix(double hueShift, double saturationShift);
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);

View file

@ -604,8 +604,9 @@ private:
/* 2C05-05 */ { 0xFF6D6D6D, 0xFF002491, 0xFF0000DA, 0xFF6D48DA, 0xFF91006D, 0xFFB6006D, 0xFFB62400, 0xFF914800, 0xFF6D4800, 0xFF244800, 0xFF006D24, 0xFF009100, 0xFF004848, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFB6B6B6, 0xFF006DDA, 0xFF0048FF, 0xFF9100FF, 0xFFB600FF, 0xFFFF0091, 0xFFFF0000, 0xFFDA6D00, 0xFF916D00, 0xFF249100, 0xFF009100, 0xFF00B66D, 0xFF009191, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFF6DB6FF, 0xFF9191FF, 0xFFDA6DFF, 0xFFFF00FF, 0xFFFF6DFF, 0xFFFF9100, 0xFFFFB600, 0xFFDADA00, 0xFF6DDA00, 0xFF00FF00, 0xFF48FFDA, 0xFF00FFFF, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFFB6DAFF, 0xFFDAB6FF, 0xFFFFB6FF, 0xFFFF91FF, 0xFFFFB6B6, 0xFFFFDA91, 0xFFFFFF48, 0xFFFFFF6D, 0xFFB6FF48, 0xFF91FF6D, 0xFF48FFDA, 0xFF91DAFF, 0xFF000000, 0xFF000000, 0xFF000000 } /* 2C05-05 */ { 0xFF6D6D6D, 0xFF002491, 0xFF0000DA, 0xFF6D48DA, 0xFF91006D, 0xFFB6006D, 0xFFB62400, 0xFF914800, 0xFF6D4800, 0xFF244800, 0xFF006D24, 0xFF009100, 0xFF004848, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFB6B6B6, 0xFF006DDA, 0xFF0048FF, 0xFF9100FF, 0xFFB600FF, 0xFFFF0091, 0xFFFF0000, 0xFFDA6D00, 0xFF916D00, 0xFF249100, 0xFF009100, 0xFF00B66D, 0xFF009191, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFF6DB6FF, 0xFF9191FF, 0xFFDA6DFF, 0xFFFF00FF, 0xFFFF6DFF, 0xFFFF9100, 0xFFFFB600, 0xFFDADA00, 0xFF6DDA00, 0xFF00FF00, 0xFF48FFDA, 0xFF00FFFF, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFFB6DAFF, 0xFFDAB6FF, 0xFFFFB6FF, 0xFFFF91FF, 0xFFFFB6B6, 0xFFFFDA91, 0xFFFFFF48, 0xFFFFFF6D, 0xFFB6FF48, 0xFF91FF6D, 0xFF48FFDA, 0xFF91DAFF, 0xFF000000, 0xFF000000, 0xFF000000 }
}; };
uint32_t _defaultPpuPalette[64] = { /* 2C02 */ 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 }; bool _isFullColorPalette = false;
uint32_t _currentPalette[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 _userPalette[512] = { };
uint32_t _currentPalette[512] = { };
const uint8_t _paletteLut[11][64] = { const uint8_t _paletteLut[11][64] = {
/* 2C02 */ { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 }, /* 2C02 */ { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 },
@ -785,20 +786,90 @@ public:
UpdateCurrentPalette(); UpdateCurrentPalette();
} }
PpuModel GetPpuModel()
{
return _ppuModel;
}
void UpdateCurrentPalette() void UpdateCurrentPalette()
{ {
if(CheckFlag(EmulationFlags::UseCustomVsPalette)) { if(CheckFlag(EmulationFlags::UseCustomVsPalette)) {
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
_currentPalette[i] = _ppuPaletteArgb[0][_paletteLut[(int)_ppuModel][i]]; for(int j = 0; j < 8; j++) {
_currentPalette[(j << 6) | i] = _userPalette[(j << 6) | (_paletteLut[(int)_ppuModel][i])];
} }
}
} else if(_ppuModel == PpuModel::Ppu2C02) {
memcpy(_currentPalette, _userPalette, sizeof(_userPalette));
} else { } else {
memcpy(_currentPalette, _ppuPaletteArgb[(int)_ppuModel], sizeof(_currentPalette)); memcpy(_currentPalette, _ppuPaletteArgb[(int)_ppuModel], sizeof(_ppuPaletteArgb[0]));
GenerateFullColorPalette(_currentPalette);
} }
} }
PpuModel GetPpuModel() uint32_t* GetRgbPalette()
{ {
return _ppuModel; return _currentPalette;
}
void GetUserRgbPalette(uint32_t* paletteBuffer)
{
memcpy(paletteBuffer, _userPalette, sizeof(_userPalette));
}
void SetUserRgbPalette(uint32_t* paletteBuffer, uint32_t size = 64)
{
if(size != 64 && size != 512) {
throw new std::runtime_error("Invalid palette buffer size");
}
memcpy(_userPalette, paletteBuffer, size * sizeof(uint32_t));
if(size == 64) {
GenerateFullColorPalette(_userPalette);
}
_isFullColorPalette = (size == 512);
UpdateCurrentPalette();
}
bool IsFullColorPalette()
{
return _isFullColorPalette;
}
void GenerateFullColorPalette(uint32_t* paletteBuffer)
{
for(int i = 0; i < 64; i++) {
for(int j = 1; j < 8; j++) {
double redColor = (uint8_t)(paletteBuffer[i] >> 16);
double greenColor = (uint8_t)(paletteBuffer[i] >> 8);
double blueColor = (uint8_t)paletteBuffer[i];
if(j & 0x01) {
//Intensify red
redColor *= 1.1;
greenColor *= 0.9;
blueColor *= 0.9;
}
if(j & 0x02) {
//Intensify green
greenColor *= 1.1;
redColor *= 0.9;
blueColor *= 0.9;
}
if(j & 0x04) {
//Intensify blue
blueColor *= 1.1;
redColor *= 0.9;
greenColor *= 0.9;
}
uint8_t r = (uint8_t)(redColor > 255 ? 255 : redColor);
uint8_t g = (uint8_t)(greenColor > 255 ? 255 : greenColor);
uint8_t b = (uint8_t)(blueColor > 255 ? 255 : blueColor);
uint32_t color = 0xFF000000 | (r << 16) | (g << 8) | b;
paletteBuffer[(j << 6) | i] = color;
}
}
} }
//0: Muted, 0.5: Default, 1.0: Max volume //0: Muted, 0.5: Default, 1.0: Max volume
@ -1189,27 +1260,6 @@ public:
return _exclusiveRefreshRate; return _exclusiveRefreshRate;
} }
uint32_t* GetRgbPalette()
{
return _currentPalette;
}
void GetRgbPalette(uint32_t* paletteBuffer)
{
memcpy(paletteBuffer, _ppuPaletteArgb[0], sizeof(_ppuPaletteArgb[0]));
}
void SetRgbPalette(uint32_t* paletteBuffer)
{
memcpy(_ppuPaletteArgb[0], paletteBuffer, sizeof(_ppuPaletteArgb[0]));
UpdateCurrentPalette();
}
bool IsDefaultPalette()
{
return memcmp(_defaultPpuPalette, GetRgbPalette(), sizeof(_defaultPpuPalette)) == 0;
}
void SetExpansionDevice(ExpansionPortDevice expansionDevice) void SetExpansionDevice(ExpansionPortDevice expansionDevice)
{ {
_expansionDevice = expansionDevice; _expansionDevice = expansionDevice;

View file

@ -226,7 +226,7 @@ PpuModel NESHeader::GetVsSystemPpuModel()
switch(Byte13 & 0x0F) { switch(Byte13 & 0x0F) {
case 0: return PpuModel::Ppu2C03; case 0: return PpuModel::Ppu2C03;
case 1: case 1:
MessageManager::Log("[iNes] Unsupport VS System Palette specified (2C03G)."); MessageManager::Log("[iNes] Unsupported VS System Palette specified (2C03G).");
return PpuModel::Ppu2C03; return PpuModel::Ppu2C03;
case 2: return PpuModel::Ppu2C04A; case 2: return PpuModel::Ppu2C04A;

View file

@ -6,8 +6,8 @@
NtscFilter::NtscFilter(shared_ptr<Console> console) : BaseVideoFilter(console) NtscFilter::NtscFilter(shared_ptr<Console> console) : BaseVideoFilter(console)
{ {
memset(_basePalette, 0, 64 * 3); memset(_palette, 0, sizeof(_palette));
_ntscData = new nes_ntsc_t(); memset(&_ntscData, 0, sizeof(_ntscData));
_ntscSetup = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; _ntscSetup = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
_ntscBuffer = new uint32_t[NES_NTSC_OUT_WIDTH(256) * 240]; _ntscBuffer = new uint32_t[NES_NTSC_OUT_WIDTH(256) * 240];
} }
@ -41,17 +41,17 @@ void NtscFilter::OnBeforeApplyFilter()
{ {
bool paletteChanged = false; bool paletteChanged = false;
uint32_t* palette = _console->GetSettings()->GetRgbPalette(); uint32_t* palette = _console->GetSettings()->GetRgbPalette();
for(int i = 0; i < 64; i++) { for(int i = 0, len = _console->GetSettings()->IsFullColorPalette() ? 512 : 64; i < len; i++) {
uint8_t r = (palette[i] >> 16) & 0xFF; uint8_t r = (palette[i] >> 16) & 0xFF;
uint8_t g = (palette[i] >> 8) & 0xFF; uint8_t g = (palette[i] >> 8) & 0xFF;
uint8_t b = palette[i] & 0xFF; uint8_t b = palette[i] & 0xFF;
if(_basePalette[i * 3] != r || _basePalette[i * 3 + 1] != g || _basePalette[i * 3 + 2] != b) { if(_palette[i * 3] != r || _palette[i * 3 + 1] != g || _palette[i * 3 + 2] != b) {
paletteChanged = true; paletteChanged = true;
_basePalette[i * 3] = (palette[i] >> 16) & 0xFF; _palette[i * 3] = (palette[i] >> 16) & 0xFF;
_basePalette[i * 3 + 1] = (palette[i] >> 8) & 0xFF; _palette[i * 3 + 1] = (palette[i] >> 8) & 0xFF;
_basePalette[i * 3 + 2] = palette[i] & 0xFF; _palette[i * 3 + 2] = palette[i] & 0xFF;
} }
} }
@ -63,7 +63,6 @@ void NtscFilter::OnBeforeApplyFilter()
if(paletteChanged || _ntscSetup.hue != pictureSettings.Hue || _ntscSetup.saturation != pictureSettings.Saturation || _ntscSetup.brightness != pictureSettings.Brightness || _ntscSetup.contrast != pictureSettings.Contrast || if(paletteChanged || _ntscSetup.hue != pictureSettings.Hue || _ntscSetup.saturation != pictureSettings.Saturation || _ntscSetup.brightness != pictureSettings.Brightness || _ntscSetup.contrast != pictureSettings.Contrast ||
_ntscSetup.artifacts != ntscSettings.Artifacts || _ntscSetup.bleed != ntscSettings.Bleed || _ntscSetup.fringing != ntscSettings.Fringing || _ntscSetup.gamma != ntscSettings.Gamma || _ntscSetup.artifacts != ntscSettings.Artifacts || _ntscSetup.bleed != ntscSettings.Bleed || _ntscSetup.fringing != ntscSettings.Fringing || _ntscSetup.gamma != ntscSettings.Gamma ||
(_ntscSetup.merge_fields == 1) != ntscSettings.MergeFields || _ntscSetup.resolution != ntscSettings.Resolution || _ntscSetup.sharpness != ntscSettings.Sharpness) { (_ntscSetup.merge_fields == 1) != ntscSettings.MergeFields || _ntscSetup.resolution != ntscSettings.Resolution || _ntscSetup.sharpness != ntscSettings.Sharpness) {
_ntscSetup.hue = pictureSettings.Hue; _ntscSetup.hue = pictureSettings.Hue;
_ntscSetup.saturation = pictureSettings.Saturation; _ntscSetup.saturation = pictureSettings.Saturation;
_ntscSetup.brightness = pictureSettings.Brightness; _ntscSetup.brightness = pictureSettings.Brightness;
@ -77,15 +76,21 @@ void NtscFilter::OnBeforeApplyFilter()
_ntscSetup.resolution = ntscSettings.Resolution; _ntscSetup.resolution = ntscSettings.Resolution;
_ntscSetup.sharpness = ntscSettings.Sharpness; _ntscSetup.sharpness = ntscSettings.Sharpness;
_ntscSetup.base_palette = _console->GetSettings()->IsDefaultPalette() ? nullptr : _basePalette; if(_console->GetSettings()->IsFullColorPalette()) {
_ntscSetup.base_palette = nullptr;
_ntscSetup.palette = _palette;
} else {
_ntscSetup.base_palette = _palette;
_ntscSetup.palette = nullptr;
}
nes_ntsc_init(_ntscData, &_ntscSetup); nes_ntsc_init(&_ntscData, &_ntscSetup);
} }
} }
void NtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer) void NtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
{ {
nes_ntsc_blit(_ntscData, ppuOutputBuffer, PPU::ScreenWidth, IsOddFrame() ? 0 : 1, PPU::ScreenWidth, 240, _ntscBuffer, NES_NTSC_OUT_WIDTH(PPU::ScreenWidth)*4); nes_ntsc_blit(&_ntscData, ppuOutputBuffer, PPU::ScreenWidth, IsOddFrame() ? 0 : 1, PPU::ScreenWidth, 240, _ntscBuffer, NES_NTSC_OUT_WIDTH(PPU::ScreenWidth)*4);
GenerateArgbFrame(_ntscBuffer); GenerateArgbFrame(_ntscBuffer);
} }
@ -152,6 +157,5 @@ void NtscFilter::GenerateArgbFrame(uint32_t *ntscBuffer)
NtscFilter::~NtscFilter() NtscFilter::~NtscFilter()
{ {
delete _ntscData;
delete[] _ntscBuffer; delete[] _ntscBuffer;
} }

View file

@ -9,9 +9,9 @@ class NtscFilter : public BaseVideoFilter
{ {
private: private:
nes_ntsc_setup_t _ntscSetup; nes_ntsc_setup_t _ntscSetup;
nes_ntsc_t* _ntscData; nes_ntsc_t _ntscData;
bool _keepVerticalRes = false; bool _keepVerticalRes = false;
uint8_t _basePalette[64 * 3]; uint8_t _palette[512 * 3];
uint32_t* _ntscBuffer; uint32_t* _ntscBuffer;
void GenerateArgbFrame(uint32_t *outputBuffer); void GenerateArgbFrame(uint32_t *outputBuffer);

View file

@ -110,17 +110,26 @@ namespace Mesen.GUI.Config
if(!string.IsNullOrWhiteSpace(videoInfo.PaletteData)) { if(!string.IsNullOrWhiteSpace(videoInfo.PaletteData)) {
try { try {
byte[] palette = System.Convert.FromBase64String(videoInfo.PaletteData); byte[] palette = Convert.FromBase64String(videoInfo.PaletteData);
if(palette.Length == 64*4) { if(palette.Length == 64*4 || palette.Length == 512*4) {
InteropEmu.SetRgbPalette(palette); InteropEmu.SetRgbPalette(palette, (UInt32)(palette.Length / 4));
} }
} catch { } } catch { }
} }
} }
public bool IsFullColorPalette()
{
if(!string.IsNullOrWhiteSpace(this.PaletteData)) {
byte[] palette = Convert.FromBase64String(this.PaletteData);
return palette.Length == 512 * 4;
}
return false;
}
public void AddPalette(string paletteName, byte[] paletteData) public void AddPalette(string paletteName, byte[] paletteData)
{ {
string base64Data = System.Convert.ToBase64String(paletteData); string base64Data = Convert.ToBase64String(paletteData);
foreach(PaletteInfo existingPalette in this.SavedPalettes) { foreach(PaletteInfo existingPalette in this.SavedPalettes) {
if(existingPalette.Name == paletteName) { if(existingPalette.Name == paletteName) {
//Update existing palette //Update existing palette
@ -144,7 +153,7 @@ namespace Mesen.GUI.Config
{ {
foreach(PaletteInfo existingPalette in this.SavedPalettes) { foreach(PaletteInfo existingPalette in this.SavedPalettes) {
if(existingPalette.Name == paletteName) { if(existingPalette.Name == paletteName) {
byte[] paletteData = System.Convert.FromBase64String(existingPalette.Palette); byte[] paletteData = Convert.FromBase64String(existingPalette.Palette);
int[] result = new int[paletteData.Length / sizeof(int)]; int[] result = new int[paletteData.Length / sizeof(int)];
Buffer.BlockCopy(paletteData, 0, result, 0, paletteData.Length); Buffer.BlockCopy(paletteData, 0, result, 0, paletteData.Length);

View file

@ -79,6 +79,10 @@ namespace Mesen.GUI.Forms.Config
AddBinding("ShowColorIndexes", chkShowColorIndexes); AddBinding("ShowColorIndexes", chkShowColorIndexes);
_paletteData = InteropEmu.GetRgbPalette(); _paletteData = InteropEmu.GetRgbPalette();
if(!ConfigManager.Config.VideoInfo.IsFullColorPalette()) {
Array.Resize(ref _paletteData, 64);
}
RefreshPalette(); RefreshPalette();
toolTip.SetToolTip(picHdNesTooltip, ResourceHelper.GetMessage("HDNesTooltip")); toolTip.SetToolTip(picHdNesTooltip, ResourceHelper.GetMessage("HDNesTooltip"));
@ -138,7 +142,7 @@ namespace Mesen.GUI.Forms.Config
{ {
byte[] result = new byte[_paletteData.Length * sizeof(int)]; byte[] result = new byte[_paletteData.Length * sizeof(int)];
Buffer.BlockCopy(_paletteData, 0, result, 0, result.Length); Buffer.BlockCopy(_paletteData, 0, result, 0, result.Length);
((VideoInfo)Entity).PaletteData = System.Convert.ToBase64String(result); ((VideoInfo)Entity).PaletteData = Convert.ToBase64String(result);
} }
protected override bool ValidateInput() protected override bool ValidateInput()
@ -215,13 +219,14 @@ namespace Mesen.GUI.Forms.Config
{ {
OpenFileDialog ofd = new OpenFileDialog(); OpenFileDialog ofd = new OpenFileDialog();
ofd.SetFilter("Palette Files (*.pal)|*.pal|All Files (*.*)|*.*"); ofd.SetFilter("Palette Files (*.pal)|*.pal|All Files (*.*)|*.*");
if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if(ofd.ShowDialog() == DialogResult.OK) {
using(FileStream paletteFile = File.OpenRead(ofd.FileName)) { using(FileStream paletteFile = File.OpenRead(ofd.FileName)) {
byte[] paletteFileData = new byte[64*3]; byte[] paletteFileData = new byte[512*3];
if(paletteFile.Read(paletteFileData, 0, 64*3) == 64*3) { int byteCount = paletteFile.Read(paletteFileData, 0, 512 * 3);
for(int i = 0; i < 64; i++) { if(byteCount == 64*3 || byteCount == 512*3) {
int fileOffset = i * 3; _paletteData = new Int32[byteCount / 3];
_paletteData[i] = (Int32)((UInt32)0xFF000000 | (UInt32)paletteFileData[fileOffset+2] | (UInt32)(paletteFileData[fileOffset+1] << 8) | (UInt32)(paletteFileData[fileOffset] << 16)); for(int i = 0; i < byteCount; i += 3) {
_paletteData[i / 3] = (Int32)((UInt32)0xFF000000 | (UInt32)paletteFileData[i + 2] | (UInt32)(paletteFileData[i + 1] << 8) | (UInt32)(paletteFileData[i] << 16));
} }
RefreshPalette(); RefreshPalette();
@ -366,7 +371,8 @@ namespace Mesen.GUI.Forms.Config
private void UpdatePalette(UInt32[] newPalette) private void UpdatePalette(UInt32[] newPalette)
{ {
for(int i = 0; i < 64; i++) { _paletteData = new Int32[newPalette.Length];
for(int i = 0; i < newPalette.Length; i++) {
_paletteData[i] = (Int32)newPalette[i]; _paletteData[i] = (Int32)newPalette[i];
} }
RefreshPalette(); RefreshPalette();
@ -439,7 +445,7 @@ namespace Mesen.GUI.Forms.Config
{ {
SaveFileDialog sfd = new SaveFileDialog(); SaveFileDialog sfd = new SaveFileDialog();
sfd.SetFilter("Palette Files (*.pal)|*.pal"); sfd.SetFilter("Palette Files (*.pal)|*.pal");
if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if(sfd.ShowDialog() == DialogResult.OK) {
List<byte>bytePalette = new List<byte>(); List<byte>bytePalette = new List<byte>();
foreach(int value in _paletteData) { foreach(int value in _paletteData) {
bytePalette.Add((byte)(value >> 16 & 0xFF)); bytePalette.Add((byte)(value >> 16 & 0xFF));

View file

@ -208,7 +208,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetVideoAspectRatio(VideoAspectRatio aspectRatio, double customRatio); [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 SetVideoFilter(VideoFilterType filter);
[DllImport(DLLPath)] public static extern void SetVideoResizeFilter(VideoResizeFilter filter); [DllImport(DLLPath)] public static extern void SetVideoResizeFilter(VideoResizeFilter filter);
[DllImport(DLLPath)] public static extern void SetRgbPalette(byte[] palette); [DllImport(DLLPath)] public static extern void SetRgbPalette(byte[] palette, UInt32 paletteSize);
[DllImport(DLLPath)] public static extern void SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity); [DllImport(DLLPath)] public static extern void SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity);
[DllImport(DLLPath)] public static extern void SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, [MarshalAs(UnmanagedType.I1)]bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, [MarshalAs(UnmanagedType.I1)]bool verticalBlend); [DllImport(DLLPath)] public static extern void SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, [MarshalAs(UnmanagedType.I1)]bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, [MarshalAs(UnmanagedType.I1)]bool verticalBlend);
[DllImport(DLLPath)] public static extern void SetInputDisplaySettings(byte visiblePorts, InputDisplayPosition displayPosition, [MarshalAs(UnmanagedType.I1)]bool displayHorizontally); [DllImport(DLLPath)] public static extern void SetInputDisplaySettings(byte visiblePorts, InputDisplayPosition displayPosition, [MarshalAs(UnmanagedType.I1)]bool displayHorizontally);
@ -816,7 +816,7 @@ namespace Mesen.GUI
public static Int32[] GetRgbPalette() public static Int32[] GetRgbPalette()
{ {
Int32[] paleteData = new Int32[64]; Int32[] paleteData = new Int32[512];
GCHandle hPaletteData = GCHandle.Alloc(paleteData, GCHandleType.Pinned); GCHandle hPaletteData = GCHandle.Alloc(paleteData, GCHandleType.Pinned);
try { try {

View file

@ -648,8 +648,8 @@ namespace InteropEmu {
DllExport void __stdcall SetVideoAspectRatio(VideoAspectRatio aspectRatio, double customRatio) { _settings->SetVideoAspectRatio(aspectRatio, customRatio); } DllExport void __stdcall SetVideoAspectRatio(VideoAspectRatio aspectRatio, double customRatio) { _settings->SetVideoAspectRatio(aspectRatio, customRatio); }
DllExport void __stdcall SetVideoFilter(VideoFilterType filter) { _settings->SetVideoFilterType(filter); } DllExport void __stdcall SetVideoFilter(VideoFilterType filter) { _settings->SetVideoFilterType(filter); }
DllExport void __stdcall SetVideoResizeFilter(VideoResizeFilter filter) { _settings->SetVideoResizeFilter(filter); } DllExport void __stdcall SetVideoResizeFilter(VideoResizeFilter filter) { _settings->SetVideoResizeFilter(filter); }
DllExport void __stdcall GetRgbPalette(uint32_t *paletteBuffer) { _settings->GetRgbPalette(paletteBuffer); } DllExport void __stdcall GetRgbPalette(uint32_t *paletteBuffer) { _settings->GetUserRgbPalette(paletteBuffer); }
DllExport void __stdcall SetRgbPalette(uint32_t *paletteBuffer) { _settings->SetRgbPalette(paletteBuffer); } DllExport void __stdcall SetRgbPalette(uint32_t *paletteBuffer, uint32_t paletteSize) { _settings->SetUserRgbPalette(paletteBuffer, paletteSize); }
DllExport void __stdcall SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity) { _settings->SetPictureSettings(brightness, contrast, saturation, hue, scanlineIntensity); } DllExport void __stdcall SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity) { _settings->SetPictureSettings(brightness, contrast, saturation, hue, scanlineIntensity); }
DllExport void __stdcall SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, bool verticalBlend) { _settings->SetNtscFilterSettings(artifacts, bleed, fringing, gamma, resolution, sharpness, mergeFields, yFilterLength, iFilterLength, qFilterLength, verticalBlend, false); } DllExport void __stdcall SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, bool verticalBlend) { _settings->SetNtscFilterSettings(artifacts, bleed, fringing, gamma, resolution, sharpness, mergeFields, yFilterLength, iFilterLength, qFilterLength, verticalBlend, false); }
DllExport void __stdcall SetPauseScreenMessage(char* message) { _settings->SetPauseScreenMessage(message); } DllExport void __stdcall SetPauseScreenMessage(char* message) { _settings->SetPauseScreenMessage(message); }

View file

@ -287,23 +287,23 @@ extern "C" {
void load_custom_palette() void load_custom_palette()
{ {
//Setup default palette in case we can't load the custom one //Setup default palette in case we can't load the custom one
_console->GetSettings()->SetRgbPalette(defaultPalette); _console->GetSettings()->SetUserRgbPalette(defaultPalette);
//Try to load the custom palette from the MesenPalette.pal file //Try to load the custom palette from the MesenPalette.pal file
string palettePath = FolderUtilities::CombinePath(FolderUtilities::GetHomeFolder(), "MesenPalette.pal"); string palettePath = FolderUtilities::CombinePath(FolderUtilities::GetHomeFolder(), "MesenPalette.pal");
uint8_t fileData[64 * 3] = {}; uint8_t fileData[512 * 3] = {};
ifstream palette(palettePath, ios::binary); ifstream palette(palettePath, ios::binary);
if(palette) { if(palette) {
palette.seekg(0, ios::end); palette.seekg(0, ios::end);
std::streampos fileSize = palette.tellg(); std::streamoff fileSize = palette.tellg();
palette.seekg(0, ios::beg); palette.seekg(0, ios::beg);
if(fileSize >= 64 * 3) { if((fileSize == 64 * 3) || (fileSize == 512 * 3)) {
palette.read((char*)fileData, 64 * 3); palette.read((char*)fileData, fileSize);
uint32_t customPalette[64]; uint32_t customPalette[512];
for(int i = 0; i < 64; i++) { for(int i = 0; i < fileSize / 3; i++) {
customPalette[i] = 0xFF000000 | fileData[i * 3 + 2] | (fileData[i * 3 + 1] << 8) | (fileData[i * 3] << 16); customPalette[i] = 0xFF000000 | fileData[i * 3 + 2] | (fileData[i * 3 + 1] << 8) | (fileData[i * 3] << 16);
} }
_console->GetSettings()->SetRgbPalette(customPalette); _console->GetSettings()->SetUserRgbPalette(customPalette, (uint32_t)fileSize / 3);
} }
} }
} }
@ -369,25 +369,25 @@ extern "C" {
if(readVariable(MesenPalette, var)) { if(readVariable(MesenPalette, var)) {
string value = string(var.value); string value = string(var.value);
if(value == "Default") { if(value == "Default") {
_console->GetSettings()->SetRgbPalette(defaultPalette); _console->GetSettings()->SetUserRgbPalette(defaultPalette);
} else if(value == "Composite Direct (by FirebrandX)") { } else if(value == "Composite Direct (by FirebrandX)") {
_console->GetSettings()->SetRgbPalette(compositeDirectPalette); _console->GetSettings()->SetUserRgbPalette(compositeDirectPalette);
} else if(value == "Nes Classic") { } else if(value == "Nes Classic") {
_console->GetSettings()->SetRgbPalette(nesClassicPalette); _console->GetSettings()->SetUserRgbPalette(nesClassicPalette);
} else if(value == "Nestopia (RGB)") { } else if(value == "Nestopia (RGB)") {
_console->GetSettings()->SetRgbPalette(nestopiaRgbPalette); _console->GetSettings()->SetUserRgbPalette(nestopiaRgbPalette);
} else if(value == "Original Hardware (by FirebrandX)") { } else if(value == "Original Hardware (by FirebrandX)") {
_console->GetSettings()->SetRgbPalette(originalHardwarePalette); _console->GetSettings()->SetUserRgbPalette(originalHardwarePalette);
} else if(value == "PVM Style (by FirebrandX)") { } else if(value == "PVM Style (by FirebrandX)") {
_console->GetSettings()->SetRgbPalette(pvmStylePalette); _console->GetSettings()->SetUserRgbPalette(pvmStylePalette);
} else if(value == "Sony CXA2025AS") { } else if(value == "Sony CXA2025AS") {
_console->GetSettings()->SetRgbPalette(sonyCxa2025AsPalette); _console->GetSettings()->SetUserRgbPalette(sonyCxa2025AsPalette);
} else if(value == "Unsaturated v6 (by FirebrandX)") { } else if(value == "Unsaturated v6 (by FirebrandX)") {
_console->GetSettings()->SetRgbPalette(unsaturatedPalette); _console->GetSettings()->SetUserRgbPalette(unsaturatedPalette);
} else if(value == "YUV v3 (by FirebrandX)") { } else if(value == "YUV v3 (by FirebrandX)") {
_console->GetSettings()->SetRgbPalette(yuvPalette); _console->GetSettings()->SetUserRgbPalette(yuvPalette);
} else if(value == "Wavebeam (by nakedarthur)") { } else if(value == "Wavebeam (by nakedarthur)") {
_console->GetSettings()->SetRgbPalette(wavebeamPalette); _console->GetSettings()->SetUserRgbPalette(wavebeamPalette);
} else if(value == "Custom") { } else if(value == "Custom") {
load_custom_palette(); load_custom_palette();
} else if(value == "Raw") { } else if(value == "Raw") {