From 2faf6aecd4b2a6fcef0833aee8d1c8939e9541fd Mon Sep 17 00:00:00 2001 From: Souryo Date: Sat, 12 Aug 2017 21:21:55 -0400 Subject: [PATCH] HD Packs: Added option to ignore/hide tiles in overscan while recording/using packs --- Core/BaseVideoFilter.h | 2 +- Core/DefaultVideoFilter.cpp | 2 +- Core/HdData.h | 17 +-- Core/HdNesPack.cpp | 14 +- Core/HdNesPack.h | 1 + Core/HdPackBuilder.cpp | 15 +- Core/HdPackBuilder.h | 2 +- Core/HdPackLoader.cpp | 16 +- Core/HdPackLoader.h | 1 + Core/HdVideoFilter.cpp | 11 ++ Core/HdVideoFilter.h | 3 +- Core/ScaleFilter.cpp | 2 +- Core/VideoDecoder.cpp | 2 +- GUI.NET/Dependencies/resources.en.xml | 1 + GUI.NET/Dependencies/resources.es.xml | 4 +- GUI.NET/Dependencies/resources.fr.xml | 4 +- GUI.NET/Dependencies/resources.ja.xml | 2 + GUI.NET/Dependencies/resources.pt.xml | 2 + GUI.NET/Dependencies/resources.ru.xml | 2 + GUI.NET/Dependencies/resources.uk.xml | 2 + GUI.NET/Forms/Cheats/frmCheat.Designer.cs | 16 +- .../HdPackEditor/frmHdPackEditor.Designer.cs | 140 ++++++++++++------ GUI.NET/Forms/HdPackEditor/frmHdPackEditor.cs | 5 +- GUI.NET/InteropEmu.cs | 1 + 24 files changed, 181 insertions(+), 86 deletions(-) diff --git a/Core/BaseVideoFilter.h b/Core/BaseVideoFilter.h index c5b6158d..4ce14395 100644 --- a/Core/BaseVideoFilter.h +++ b/Core/BaseVideoFilter.h @@ -17,7 +17,6 @@ private: void UpdateBufferSize(); protected: - OverscanDimensions GetOverscan(); virtual void ApplyFilter(uint16_t *ppuOutputBuffer) = 0; virtual void OnBeforeApplyFilter(); @@ -30,5 +29,6 @@ public: void TakeScreenshot(); void TakeScreenshot(string filename, std::stringstream *stream = nullptr); + virtual OverscanDimensions GetOverscan(); virtual FrameInfo GetFrameInfo() = 0; }; \ No newline at end of file diff --git a/Core/DefaultVideoFilter.cpp b/Core/DefaultVideoFilter.cpp index b1f45f5d..df0c6ebd 100644 --- a/Core/DefaultVideoFilter.cpp +++ b/Core/DefaultVideoFilter.cpp @@ -54,7 +54,7 @@ void DefaultVideoFilter::OnBeforeApplyFilter() void DefaultVideoFilter::DecodePpuBuffer(uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, bool displayScanlines) { - OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions(); + OverscanDimensions overscan = GetOverscan(); double scanlineIntensity = 1.0 - EmulationSettings::GetPictureSettings().ScanlineIntensity; for(uint32_t i = overscan.Top, iMax = 240 - overscan.Bottom; i < iMax; i++) { if(displayScanlines && (i + overscan.Top) % 2 == 0) { diff --git a/Core/HdData.h b/Core/HdData.h index 42ebd4d8..b8aedc99 100644 --- a/Core/HdData.h +++ b/Core/HdData.h @@ -384,24 +384,19 @@ struct HdPackData std::unordered_map> TileByKey; std::unordered_map PatchesByHash; vector Palette; - vector PaletteBackup; + + bool HasOverscanConfig = false; + OverscanDimensions Overscan; + uint32_t Scale = 1; uint32_t Version = 0; uint32_t OptionFlags = 0; - HdPackData() - { - } + HdPackData() { } + ~HdPackData() { } HdPackData(const HdPackData&) = delete; HdPackData& operator=(const HdPackData&) = delete; - - ~HdPackData() - { - if(PaletteBackup.size() == 0x40) { - EmulationSettings::SetRgbPalette(PaletteBackup.data()); - } - } }; enum class HdPackOptions diff --git a/Core/HdNesPack.cpp b/Core/HdNesPack.cpp index f92bc847..4dbcf489 100644 --- a/Core/HdNesPack.cpp +++ b/Core/HdNesPack.cpp @@ -71,7 +71,7 @@ bool HdNesPack::DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo return false; } - uint32_t bgColor = EmulationSettings::GetRgbPalette()[tileInfo.PpuBackgroundColor]; + uint32_t bgColor = _palette[tileInfo.PpuBackgroundColor]; uint32_t scale = GetScale(); if(hdPackTileInfo.IsFullyTransparent) { if(drawBackground) { @@ -150,14 +150,12 @@ void HdNesPack::OnBeforeApplyFilter(HdPpuPixelInfo *screenTiles) { HdPackData* hdData = Console::GetHdData(); + _palette = hdData->Palette.size() == 0x40 ? hdData->Palette.data() : EmulationSettings::GetRgbPalette(); + if(hdData->OptionFlags & (int)HdPackOptions::NoSpriteLimit) { EmulationSettings::SetFlags(EmulationFlags::RemoveSpriteLimit | EmulationFlags::AdaptiveSpriteLimit); } - if(hdData->Palette.size() == 0x40) { - EmulationSettings::SetRgbPalette(hdData->Palette.data()); - } - _backgroundIndex = -1; for(size_t i = 0; i < hdData->Backgrounds.size(); i++) { bool isMatch = true; @@ -258,7 +256,7 @@ void HdNesPack::GetPixels(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y, H if(hdPackSpriteInfo) { needBg &= !DrawTile(pixelInfo.Sprite[k], *hdPackSpriteInfo, outputBuffer, screenWidth, needBg); } else if(pixelInfo.Sprite[k].SpriteColorIndex != 0) { - DrawColor(EmulationSettings::GetRgbPalette()[pixelInfo.Sprite[k].SpriteColor], outputBuffer, hdData->Scale, screenWidth); + DrawColor(_palette[pixelInfo.Sprite[k].SpriteColor], outputBuffer, hdData->Scale, screenWidth); needBg = false; } } @@ -282,7 +280,7 @@ void HdNesPack::GetPixels(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y, H if(useCustomBackground) { DrawCustomBackground(outputBuffer, x, y, hdData->Scale, screenWidth); } else { - DrawColor(EmulationSettings::GetRgbPalette()[pixelInfo.Tile.BgColor], outputBuffer, hdData->Scale, screenWidth); + DrawColor(_palette[pixelInfo.Tile.BgColor], outputBuffer, hdData->Scale, screenWidth); } } } @@ -294,7 +292,7 @@ void HdNesPack::GetPixels(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y, H if(hdPackSpriteInfo) { DrawTile(pixelInfo.Sprite[k], *hdPackSpriteInfo, outputBuffer, screenWidth, false); } else if(pixelInfo.Sprite[k].SpriteColorIndex != 0) { - DrawColor(EmulationSettings::GetRgbPalette()[pixelInfo.Sprite[k].SpriteColor], outputBuffer, hdData->Scale, screenWidth); + DrawColor(_palette[pixelInfo.Sprite[k].SpriteColor], outputBuffer, hdData->Scale, screenWidth); } } } diff --git a/Core/HdNesPack.h b/Core/HdNesPack.h index 0027d1e7..153aaae4 100644 --- a/Core/HdNesPack.h +++ b/Core/HdNesPack.h @@ -6,6 +6,7 @@ class HdNesPack { private: int32_t _backgroundIndex = -1; + uint32_t* _palette = nullptr; __forceinline void BlendColors(uint8_t output[4], uint8_t input[4]); __forceinline uint32_t AdjustBrightness(uint8_t input[4], uint16_t brightness); diff --git a/Core/HdPackBuilder.cpp b/Core/HdPackBuilder.cpp index 7da88466..ad205eae 100644 --- a/Core/HdPackBuilder.cpp +++ b/Core/HdPackBuilder.cpp @@ -11,6 +11,7 @@ enum HdPackRecordFlags UseLargeSprites = 1, SortByUsageFrequency = 2, GroupBlankTiles = 4, + IgnoreOverscan = 8, }; HdPackBuilder::HdPackBuilder(string saveFolder, ScaleFilterType filterType, uint32_t scale, uint32_t flags, uint32_t chrRamBankSize, bool isChrRam) @@ -78,8 +79,16 @@ void HdPackBuilder::AddTile(HdPackTileInfo *tile, uint32_t usageCount) _tileUsageCount[tile->GetKey(false)] = usageCount; } -void HdPackBuilder::ProcessTile(int x, int y, uint16_t tileAddr, HdPpuTileInfo &tile, BaseMapper *mapper, bool isSprite, uint32_t chrBankHash) +void HdPackBuilder::ProcessTile(uint32_t x, uint32_t y, uint16_t tileAddr, HdPpuTileInfo &tile, BaseMapper *mapper, bool isSprite, uint32_t chrBankHash) { + if(_flags & HdPackRecordFlags::IgnoreOverscan) { + OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions(); + if(x < overscan.Left || y < overscan.Top || (PPU::ScreenWidth - x - 1) < overscan.Right || (PPU::ScreenHeight - y - 1) < overscan.Bottom) { + //Ignore tiles inside overscan + return; + } + } + auto result = _tileUsageCount.find(tile.GetKey(false)); if(result == _tileUsageCount.end()) { //Check to see if a default tile matches @@ -199,6 +208,10 @@ void HdPackBuilder::SaveHdPack() ss << "100" << std::endl; ss << "" << _hdData.Scale << std::endl; ss << "" << Console::GetHashInfo().Sha1Hash << std::endl; + if(_flags & HdPackRecordFlags::IgnoreOverscan) { + OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions(); + ss << "" << overscan.Top << "," << overscan.Right << "," << overscan.Bottom << "," << overscan.Left << std::endl; + } int tileDimension = 8 * _hdData.Scale; int pngDimension = 16 * tileDimension; diff --git a/Core/HdPackBuilder.h b/Core/HdPackBuilder.h index adce5e96..957775c8 100644 --- a/Core/HdPackBuilder.h +++ b/Core/HdPackBuilder.h @@ -41,7 +41,7 @@ public: HdPackBuilder(string saveFolder, ScaleFilterType filterType, uint32_t scale, uint32_t flags, uint32_t chrRamBankSize, bool isChrRam); ~HdPackBuilder(); - void ProcessTile(int x, int y, uint16_t tileAddr, HdPpuTileInfo& tile, BaseMapper* mapper, bool isSprite, uint32_t chrBankHash); + void ProcessTile(uint32_t x, uint32_t y, uint16_t tileAddr, HdPpuTileInfo& tile, BaseMapper* mapper, bool isSprite, uint32_t chrBankHash); void SaveHdPack(); static void GetChrBankList(uint32_t *banks); diff --git a/Core/HdPackLoader.cpp b/Core/HdPackLoader.cpp index e4e8f4b0..ac7535e0 100644 --- a/Core/HdPackLoader.cpp +++ b/Core/HdPackLoader.cpp @@ -128,6 +128,9 @@ bool HdPackLoader::LoadPack() } else if(lineContent.substr(0, 7) == "") { lineContent = lineContent.substr(7); _data->Scale = std::stoi(lineContent); + } else if(lineContent.substr(0, 10) == "") { + tokens = StringUtilities::Split(lineContent.substr(10), ','); + ProcessOverscanTag(tokens); } else if(lineContent.substr(0, 5) == "") { lineContent = lineContent.substr(5); if(!ProcessImgTag(lineContent)) { @@ -175,6 +178,17 @@ bool HdPackLoader::ProcessImgTag(string src) } } +void HdPackLoader::ProcessOverscanTag(vector &tokens) +{ + OverscanDimensions overscan; + overscan.Top = std::stoi(tokens[0]); + overscan.Right = std::stoi(tokens[1]); + overscan.Bottom = std::stoi(tokens[2]); + overscan.Left = std::stoi(tokens[3]); + _data->HasOverscanConfig = true; + _data->Overscan = overscan; +} + void HdPackLoader::ProcessPatchTag(vector &tokens) { if(tokens[1].size() != 40) { @@ -404,8 +418,6 @@ void HdPackLoader::LoadCustomPalette() } if(paletteData.size() == 0x40) { - _data->PaletteBackup = vector(0x40, 0); - EmulationSettings::GetRgbPalette(_data->PaletteBackup.data()); _data->Palette = paletteData; } } diff --git a/Core/HdPackLoader.h b/Core/HdPackLoader.h index e2750e78..274d8b58 100644 --- a/Core/HdPackLoader.h +++ b/Core/HdPackLoader.h @@ -29,6 +29,7 @@ private: bool ProcessImgTag(string src); void ProcessPatchTag(vector &tokens); + void ProcessOverscanTag(vector &tokens); void ProcessConditionTag(vector &tokens); void ProcessTileTag(vector &tokens, vector conditions); void ProcessBackgroundTag(vector &tokens, vector conditions); diff --git a/Core/HdVideoFilter.cpp b/Core/HdVideoFilter.cpp index 5adc6df1..e73951ae 100644 --- a/Core/HdVideoFilter.cpp +++ b/Core/HdVideoFilter.cpp @@ -2,6 +2,7 @@ #include "PPU.h" #include "HdNesPack.h" #include "HdVideoFilter.h" +#include "Console.h" HdVideoFilter::HdVideoFilter() { @@ -16,6 +17,16 @@ FrameInfo HdVideoFilter::GetFrameInfo() return { overscan.GetScreenWidth() * hdScale, overscan.GetScreenHeight() * hdScale, PPU::ScreenWidth*hdScale, PPU::ScreenHeight*hdScale, 4 }; } +OverscanDimensions HdVideoFilter::GetOverscan() +{ + HdPackData* hdData = Console::GetHdData(); + if(hdData->HasOverscanConfig) { + return hdData->Overscan; + } else { + return BaseVideoFilter::GetOverscan(); + } +} + void HdVideoFilter::SetHdScreenTiles(HdPpuPixelInfo *screenTiles) { _hdScreenTiles = screenTiles; diff --git a/Core/HdVideoFilter.h b/Core/HdVideoFilter.h index 10761c91..7d920822 100644 --- a/Core/HdVideoFilter.h +++ b/Core/HdVideoFilter.h @@ -15,6 +15,7 @@ public: void ApplyFilter(uint16_t *ppuOutputBuffer); FrameInfo GetFrameInfo(); - + OverscanDimensions GetOverscan() override; + void SetHdScreenTiles(HdPpuPixelInfo *screenTiles); }; diff --git a/Core/ScaleFilter.cpp b/Core/ScaleFilter.cpp index 58685ed5..b620035d 100644 --- a/Core/ScaleFilter.cpp +++ b/Core/ScaleFilter.cpp @@ -58,7 +58,7 @@ void ScaleFilter::ApplyFilter(uint16_t *ppuOutputBuffer) { DecodePpuBuffer(ppuOutputBuffer, _decodedPpuBuffer, false); - OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions(); + OverscanDimensions overscan = GetOverscan(); uint32_t height = overscan.GetScreenHeight(); uint32_t width = overscan.GetScreenWidth(); uint32_t* outputBuffer = (uint32_t*)GetOutputBuffer(); diff --git a/Core/VideoDecoder.cpp b/Core/VideoDecoder.cpp index d7157b65..6b4f5b68 100644 --- a/Core/VideoDecoder.cpp +++ b/Core/VideoDecoder.cpp @@ -49,7 +49,7 @@ FrameInfo VideoDecoder::GetFrameInfo() void VideoDecoder::GetScreenSize(ScreenSize &size, bool ignoreScale) { if(_videoFilter) { - OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions(); + OverscanDimensions overscan = _videoFilter->GetOverscan(); FrameInfo frameInfo{ overscan.GetScreenWidth(), overscan.GetScreenHeight(), PPU::ScreenWidth, PPU::ScreenHeight, 4 }; double aspectRatio = EmulationSettings::GetAspectRatio(); double scale = (ignoreScale ? 1 : EmulationSettings::GetVideoScale()); diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml index 2083b33e..31cf27e0 100644 --- a/GUI.NET/Dependencies/resources.en.xml +++ b/GUI.NET/Dependencies/resources.en.xml @@ -52,6 +52,7 @@ When this option is enabled, the tiles in PNG files are sorted by the frequency at which they are shown on the screen while recording (more common palettes will be grouped together in the first PNG for a specific bank number. If this option is unchecked, the PNGs will be sorted by palette - each PNG will only contain up to 4 different colors in this case. This option groups all the blank tiles sequentially into the same PNG files - this helps reduce the number of PNG files produced by removing almost-empty PNG files containing only blank tiles. When enabled, this option will alter the display order of CHR banks that contain only sprites to make the sprites easier to edit in the PNG file. + When enabled, this will make the builder ignore any pixels in the overscan area. This is useful in games that contain glitches on the outer edge of the screen. Incorrect palette combinations due to these glitches will be ignored and won't be shown in the PNG files. You are running the latest version of Mesen Patch and reset the current game? diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml index 36ad1548..74815144 100644 --- a/GUI.NET/Dependencies/resources.es.xml +++ b/GUI.NET/Dependencies/resources.es.xml @@ -572,6 +572,7 @@ Ordenar páginas por frecuencia de uso Usar sprites de 8x16 Agrupar tiles blancas + Ignore tiles at the edges of the screen (overscan) Guardar en: Buscar... Empezar a grabar @@ -658,7 +659,8 @@ Cuando esta opción está habilitada, las tiles en los ficheros PNG se ordenan por la frecuencia en que se muestren en la pantalla mientras se esté grabando (paletas más comunes se agruparan conjuntamente en el primer archivo para un número de banco específico. Si esta casilla está desmarcada, los archivos PNG se ordenarán por paleta - en ese caso, cada archivo PNG contendrá solamente 4 colores diferentes. Esta opción agrupa todas las tiles blancas secuencialmente a los mismos ficheros PNG - esto ayuda a reducir el número de archivos PNG producidos, ya que eliminan archivos PNG casi vacíos que solo contienen tiles blancas. Si está habilitada, esta opción alterará el orden de aparición de los bancos CHR que solo contengan sprites a fin de hacer que los sprites sean más fáciles de editar en el fichero PNG. - + When enabled, this will make the builder ignore any pixels in the overscan area. This is useful in games that contain glitches on the outer edge of the screen. Incorrect palette combinations due to these glitches will be ignored and won't be shown in the PNG files. + Ya utiliza la versión mas reciente de Mesen. ¿Aplicar el parche y reiniciar el juego? Elija la ROM que corresponde al archivo IPS/UPS/BPS seleccionado. diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml index 550da061..2179ed7e 100644 --- a/GUI.NET/Dependencies/resources.fr.xml +++ b/GUI.NET/Dependencies/resources.fr.xml @@ -586,6 +586,7 @@ Trier par fréquence d'utilisation Utiliser le mode d'affichage 8x16 pour les sprites Regrouper les tiles vides + Ignorer les tiles qui se trouvent dans l'overscan Dossier de sauvegarde : Parcourir... Enregistrer @@ -673,7 +674,8 @@ Quand cette option est activée, les tiles sont triés selon la fréquence à laquelle elles apparaissent à l'écran pendant l'enregistrement (les palettes de couleurs plus fréquentes seront regroupées dans la même image PNG pour une banque donnée. Si cette option est désactivée, les tiles seront regroupées par palette, donc chaque image PNG comportera au plus 4 couleurs différentes. Cette option regroupe toutes les tiles "vides" dans les mêmes fichiers PNG. Ceci permet de réduire le nombre de fichiers PNG inutilement créés par le créateur de HD Packs. Cette option change la mode d'afficher pour les banques ne contenant que des sprites. Les fichiers PNG seront créées d'une façon à favoriser l'affichage des sprites de dimension 8x16. - + Quand cette option est activée, les pixels contenus dans la région d'overscan sont ignorés. Ceci permet d'éviter la capture des tiles buggés qui sont parfois visibles aux bords de l'écran. Les combinaisons de palette incorrectes qui se retrouvent aux bords de l'écran ne seront pas dans les fichiers PNG. + Vous utilisez déjà la version la plus récente de Mesen. Appliquer la patch et faire un reset du jeu? Choisissez un ROM qui correspond au fichier IPS/UPS/BPS choisi. diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml index d2162300..6e40f291 100644 --- a/GUI.NET/Dependencies/resources.ja.xml +++ b/GUI.NET/Dependencies/resources.ja.xml @@ -569,6 +569,7 @@ タイルを使用頻度順に並べ替えする 8x16スプライト表示モードを使う 空っぽなタイルとまとめて保存する + オーバースキャンの中にあるタイルを無視する セーブフォルダ: 参照... 開始 @@ -656,6 +657,7 @@ When this option is enabled, the tiles in PNG files are sorted by the frequency at which they are shown on the screen while recording (more common palettes will be grouped together in the first PNG for a specific bank number. If this option is unchecked, the PNGs will be sorted by palette - each PNG will only contain up to 4 different colors in this case. This option groups all the blank tiles sequentially into the same PNG files - this helps reduce the number of PNG files produced by removing almost-empty PNG files containing only blank tiles. When enabled, this option will alter the display order of CHR banks that contain only sprites to make the sprites easier to edit in the PNG file. + When enabled, this will make the builder ignore any pixels in the overscan area. This is useful in games that contain glitches on the outer edge of the screen. Incorrect palette combinations due to these glitches will be ignored and won't be shown in the PNG files. 既にMesenの最新のバージョンを使っています。 パッチファイルを当てて、ゲームをリセットしますか? diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml index 2df317c5..0e3ee9a9 100644 --- a/GUI.NET/Dependencies/resources.pt.xml +++ b/GUI.NET/Dependencies/resources.pt.xml @@ -572,6 +572,7 @@ Ordenar páginas por frequência de utilização Usar sprite de 8x16 Group blank tiles + Ignore tiles at the edges of the screen (overscan) Save Folder: Browse... Start Recording @@ -658,6 +659,7 @@ When this option is enabled, the tiles in PNG files are sorted by the frequency at which they are shown on the screen while recording (more common palettes will be grouped together in the first PNG for a specific bank number. If this option is unchecked, the PNGs will be sorted by palette - each PNG will only contain up to 4 different colors in this case. This option groups all the blank tiles sequentially into the same PNG files - this helps reduce the number of PNG files produced by removing almost-empty PNG files containing only blank tiles. When enabled, this option will alter the display order of CHR banks that contain only sprites to make the sprites easier to edit in the PNG file. + When enabled, this will make the builder ignore any pixels in the overscan area. This is useful in games that contain glitches on the outer edge of the screen. Incorrect palette combinations due to these glitches will be ignored and won't be shown in the PNG files. Já utiliza a versão mais recente do Mesen. Aplicar o patch e reiniciar o jogo? diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml index 676e8599..ef559ee2 100644 --- a/GUI.NET/Dependencies/resources.ru.xml +++ b/GUI.NET/Dependencies/resources.ru.xml @@ -576,6 +576,7 @@ Sort pages by usage frequency Use 8x16 sprite display mode Group blank tiles + Ignore tiles at the edges of the screen (overscan) Save Folder: Browse... Start Recording @@ -663,6 +664,7 @@ When this option is enabled, the tiles in PNG files are sorted by the frequency at which they are shown on the screen while recording (more common palettes will be grouped together in the first PNG for a specific bank number. If this option is unchecked, the PNGs will be sorted by palette - each PNG will only contain up to 4 different colors in this case. This option groups all the blank tiles sequentially into the same PNG files - this helps reduce the number of PNG files produced by removing almost-empty PNG files containing only blank tiles. When enabled, this option will alter the display order of CHR banks that contain only sprites to make the sprites easier to edit in the PNG file. + When enabled, this will make the builder ignore any pixels in the overscan area. This is useful in games that contain glitches on the outer edge of the screen. Incorrect palette combinations due to these glitches will be ignored and won't be shown in the PNG files. Вы используете последнюю версию Mesen Пропатчить и сбросить текущую игру? diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml index c16fe9b6..b2ae280a 100644 --- a/GUI.NET/Dependencies/resources.uk.xml +++ b/GUI.NET/Dependencies/resources.uk.xml @@ -576,6 +576,7 @@ Сортування сторінок за частотою використання Використовувати режим відображення спрайтiв 8x16 Групувати порожнi тайли + Ignore tiles at the edges of the screen (overscan) Зберегти папку: Огляд... Почати запис @@ -663,6 +664,7 @@ When this option is enabled, the tiles in PNG files are sorted by the frequency at which they are shown on the screen while recording (more common palettes will be grouped together in the first PNG for a specific bank number. If this option is unchecked, the PNGs will be sorted by palette - each PNG will only contain up to 4 different colors in this case. This option groups all the blank tiles sequentially into the same PNG files - this helps reduce the number of PNG files produced by removing almost-empty PNG files containing only blank tiles. When enabled, this option will alter the display order of CHR banks that contain only sprites to make the sprites easier to edit in the PNG file. + When enabled, this will make the builder ignore any pixels in the overscan area. This is useful in games that contain glitches on the outer edge of the screen. Incorrect palette combinations due to these glitches will be ignored and won't be shown in the PNG files. Ви використовуєте останню версію Mesen Пропатчити і скинути поточну гру? diff --git a/GUI.NET/Forms/Cheats/frmCheat.Designer.cs b/GUI.NET/Forms/Cheats/frmCheat.Designer.cs index 0962d3e2..801d34aa 100644 --- a/GUI.NET/Forms/Cheats/frmCheat.Designer.cs +++ b/GUI.NET/Forms/Cheats/frmCheat.Designer.cs @@ -60,7 +60,7 @@ // // baseConfigPanel // - this.baseConfigPanel.Location = new System.Drawing.Point(0, 270); + this.baseConfigPanel.Location = new System.Drawing.Point(0, 273); this.baseConfigPanel.Size = new System.Drawing.Size(385, 29); // // tableLayoutPanel2 @@ -84,7 +84,7 @@ 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.Size = new System.Drawing.Size(385, 270); + this.tableLayoutPanel2.Size = new System.Drawing.Size(385, 273); this.tableLayoutPanel2.TabIndex = 3; // // label2 @@ -135,7 +135,7 @@ this.grpCode.Dock = System.Windows.Forms.DockStyle.Fill; this.grpCode.Location = new System.Drawing.Point(3, 81); this.grpCode.Name = "grpCode"; - this.grpCode.Size = new System.Drawing.Size(379, 186); + this.grpCode.Size = new System.Drawing.Size(379, 189); this.grpCode.TabIndex = 3; this.grpCode.TabStop = false; this.grpCode.Text = "Code"; @@ -158,7 +158,7 @@ this.tlpAdd.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tlpAdd.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tlpAdd.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tlpAdd.Size = new System.Drawing.Size(373, 167); + this.tlpAdd.Size = new System.Drawing.Size(373, 170); this.tlpAdd.TabIndex = 0; // // radCustom @@ -232,7 +232,7 @@ this.tlpCustom.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tlpCustom.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tlpCustom.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tlpCustom.Size = new System.Drawing.Size(250, 109); + this.tlpCustom.Size = new System.Drawing.Size(250, 112); this.tlpCustom.TabIndex = 4; // // lblAddress @@ -353,13 +353,13 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(385, 299); + this.ClientSize = new System.Drawing.Size(385, 302); this.Controls.Add(this.tableLayoutPanel2); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(401, 337); + this.MaximumSize = new System.Drawing.Size(401, 340); this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(401, 337); + this.MinimumSize = new System.Drawing.Size(401, 340); this.Name = "frmCheat"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Edit Cheat"; diff --git a/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.Designer.cs b/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.Designer.cs index f6737fdc..96e751d8 100644 --- a/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.Designer.cs +++ b/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.Designer.cs @@ -37,6 +37,9 @@ this.lblChrBank = new System.Windows.Forms.Label(); this.grpOptions = new System.Windows.Forms.GroupBox(); this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.chkIgnoreOverscan = new System.Windows.Forms.CheckBox(); + this.picIgnoreOverscanHelp = new System.Windows.Forms.PictureBox(); this.lblBankSize = new System.Windows.Forms.Label(); this.lblScale = new System.Windows.Forms.Label(); this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); @@ -54,20 +57,22 @@ this.flowLayoutPanel6 = new System.Windows.Forms.FlowLayoutPanel(); this.cboScale = new System.Windows.Forms.ComboBox(); this.picScaleHelp = new System.Windows.Forms.PictureBox(); - this.lblFolder = new System.Windows.Forms.Label(); - this.txtSaveFolder = new System.Windows.Forms.TextBox(); - this.btnSelectFolder = new System.Windows.Forms.Button(); this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); this.btnStartRecording = new System.Windows.Forms.Button(); this.btnStopRecording = new System.Windows.Forms.Button(); - this.tmrRefresh = new System.Windows.Forms.Timer(this.components); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); + this.btnSelectFolder = new System.Windows.Forms.Button(); + this.txtSaveFolder = new System.Windows.Forms.TextBox(); + this.lblFolder = new System.Windows.Forms.Label(); + this.tmrRefresh = new System.Windows.Forms.Timer(this.components); this.tableLayoutPanel1.SuspendLayout(); this.grpPreview.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picBankPreview)).BeginInit(); this.grpOptions.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picIgnoreOverscanHelp)).BeginInit(); this.flowLayoutPanel3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picGroupBlankHelp)).BeginInit(); this.flowLayoutPanel4.SuspendLayout(); @@ -190,6 +195,7 @@ this.tableLayoutPanel2.ColumnCount = 2; this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel1, 0, 6); this.tableLayoutPanel2.Controls.Add(this.lblBankSize, 0, 1); this.tableLayoutPanel2.Controls.Add(this.lblScale, 0, 0); this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel3, 0, 2); @@ -200,17 +206,49 @@ this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; - this.tableLayoutPanel2.RowCount = 6; + this.tableLayoutPanel2.RowCount = 8; + 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()); 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()); - 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.Percent, 100F)); this.tableLayoutPanel2.Size = new System.Drawing.Size(325, 291); this.tableLayoutPanel2.TabIndex = 0; // + // flowLayoutPanel1 + // + this.tableLayoutPanel2.SetColumnSpan(this.flowLayoutPanel1, 2); + this.flowLayoutPanel1.Controls.Add(this.chkIgnoreOverscan); + this.flowLayoutPanel1.Controls.Add(this.picIgnoreOverscanHelp); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 114); + this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(325, 20); + this.flowLayoutPanel1.TabIndex = 19; + // + // chkIgnoreOverscan + // + this.chkIgnoreOverscan.AutoSize = true; + this.chkIgnoreOverscan.Location = new System.Drawing.Point(3, 3); + this.chkIgnoreOverscan.Name = "chkIgnoreOverscan"; + this.chkIgnoreOverscan.Size = new System.Drawing.Size(257, 17); + this.chkIgnoreOverscan.TabIndex = 17; + this.chkIgnoreOverscan.Text = "Ignore tiles at the edges of the screen (overscan)"; + this.chkIgnoreOverscan.UseVisualStyleBackColor = true; + // + // picIgnoreOverscanHelp + // + this.picIgnoreOverscanHelp.Image = global::Mesen.GUI.Properties.Resources.Help; + this.picIgnoreOverscanHelp.Location = new System.Drawing.Point(266, 3); + this.picIgnoreOverscanHelp.Name = "picIgnoreOverscanHelp"; + this.picIgnoreOverscanHelp.Size = new System.Drawing.Size(16, 16); + this.picIgnoreOverscanHelp.TabIndex = 18; + this.picIgnoreOverscanHelp.TabStop = false; + // // lblBankSize // this.lblBankSize.Anchor = System.Windows.Forms.AnchorStyles.Left; @@ -332,6 +370,7 @@ // this.flpBankSize.Controls.Add(this.cboChrBankSize); this.flpBankSize.Controls.Add(this.picBankSizeHelp); + this.flpBankSize.Dock = System.Windows.Forms.DockStyle.Fill; this.flpBankSize.Location = new System.Drawing.Point(90, 24); this.flpBankSize.Margin = new System.Windows.Forms.Padding(0); this.flpBankSize.Name = "flpBankSize"; @@ -348,13 +387,13 @@ "4 KB"}); this.cboChrBankSize.Location = new System.Drawing.Point(3, 3); this.cboChrBankSize.Name = "cboChrBankSize"; - this.cboChrBankSize.Size = new System.Drawing.Size(121, 21); + this.cboChrBankSize.Size = new System.Drawing.Size(105, 21); this.cboChrBankSize.TabIndex = 10; // // picBankSizeHelp // this.picBankSizeHelp.Image = global::Mesen.GUI.Properties.Resources.Help; - this.picBankSizeHelp.Location = new System.Drawing.Point(130, 5); + this.picBankSizeHelp.Location = new System.Drawing.Point(114, 5); this.picBankSizeHelp.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); this.picBankSizeHelp.Name = "picBankSizeHelp"; this.picBankSizeHelp.Size = new System.Drawing.Size(16, 16); @@ -365,6 +404,7 @@ // this.flowLayoutPanel6.Controls.Add(this.cboScale); this.flowLayoutPanel6.Controls.Add(this.picScaleHelp); + this.flowLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill; this.flowLayoutPanel6.Location = new System.Drawing.Point(90, 0); this.flowLayoutPanel6.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanel6.Name = "flowLayoutPanel6"; @@ -377,50 +417,19 @@ this.cboScale.FormattingEnabled = true; this.cboScale.Location = new System.Drawing.Point(3, 3); this.cboScale.Name = "cboScale"; - this.cboScale.Size = new System.Drawing.Size(121, 21); + this.cboScale.Size = new System.Drawing.Size(105, 21); this.cboScale.TabIndex = 5; // // picScaleHelp // this.picScaleHelp.Image = global::Mesen.GUI.Properties.Resources.Help; - this.picScaleHelp.Location = new System.Drawing.Point(130, 5); + this.picScaleHelp.Location = new System.Drawing.Point(114, 5); this.picScaleHelp.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); this.picScaleHelp.Name = "picScaleHelp"; this.picScaleHelp.Size = new System.Drawing.Size(16, 16); this.picScaleHelp.TabIndex = 12; this.picScaleHelp.TabStop = false; // - // lblFolder - // - this.lblFolder.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.lblFolder.AutoSize = true; - this.lblFolder.Location = new System.Drawing.Point(3, 8); - this.lblFolder.Name = "lblFolder"; - this.lblFolder.Size = new System.Drawing.Size(67, 13); - this.lblFolder.TabIndex = 0; - this.lblFolder.Text = "Save Folder:"; - // - // txtSaveFolder - // - this.txtSaveFolder.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtSaveFolder.Location = new System.Drawing.Point(76, 3); - this.txtSaveFolder.Name = "txtSaveFolder"; - this.txtSaveFolder.ReadOnly = true; - this.txtSaveFolder.Size = new System.Drawing.Size(465, 20); - this.txtSaveFolder.TabIndex = 1; - this.txtSaveFolder.TabStop = false; - // - // btnSelectFolder - // - this.btnSelectFolder.AutoSize = true; - this.btnSelectFolder.Location = new System.Drawing.Point(547, 3); - this.btnSelectFolder.Name = "btnSelectFolder"; - this.btnSelectFolder.Size = new System.Drawing.Size(62, 23); - this.btnSelectFolder.TabIndex = 8; - this.btnSelectFolder.Text = "Browse..."; - this.btnSelectFolder.UseVisualStyleBackColor = true; - this.btnSelectFolder.Click += new System.EventHandler(this.btnSelectFolder_Click); - // // flowLayoutPanel2 // this.flowLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); @@ -463,11 +472,6 @@ this.btnStopRecording.Visible = false; this.btnStopRecording.Click += new System.EventHandler(this.btnStopRecording_Click); // - // tmrRefresh - // - this.tmrRefresh.Interval = 200; - this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick); - // // tableLayoutPanel4 // this.tableLayoutPanel4.ColumnCount = 3; @@ -480,13 +484,49 @@ this.tableLayoutPanel4.Controls.Add(this.lblFolder, 0, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0); + this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 1; this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel4.Size = new System.Drawing.Size(612, 29); this.tableLayoutPanel4.TabIndex = 9; // + // btnSelectFolder + // + this.btnSelectFolder.AutoSize = true; + this.btnSelectFolder.Location = new System.Drawing.Point(547, 3); + this.btnSelectFolder.Name = "btnSelectFolder"; + this.btnSelectFolder.Size = new System.Drawing.Size(62, 23); + this.btnSelectFolder.TabIndex = 8; + this.btnSelectFolder.Text = "Browse..."; + this.btnSelectFolder.UseVisualStyleBackColor = true; + this.btnSelectFolder.Click += new System.EventHandler(this.btnSelectFolder_Click); + // + // txtSaveFolder + // + this.txtSaveFolder.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtSaveFolder.Location = new System.Drawing.Point(76, 3); + this.txtSaveFolder.Name = "txtSaveFolder"; + this.txtSaveFolder.ReadOnly = true; + this.txtSaveFolder.Size = new System.Drawing.Size(465, 20); + this.txtSaveFolder.TabIndex = 1; + this.txtSaveFolder.TabStop = false; + // + // lblFolder + // + this.lblFolder.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblFolder.AutoSize = true; + this.lblFolder.Location = new System.Drawing.Point(3, 8); + this.lblFolder.Name = "lblFolder"; + this.lblFolder.Size = new System.Drawing.Size(67, 13); + this.lblFolder.TabIndex = 0; + this.lblFolder.Text = "Save Folder:"; + // + // tmrRefresh + // + this.tmrRefresh.Interval = 200; + this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick); + // // frmHdPackEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -507,6 +547,9 @@ this.grpOptions.ResumeLayout(false); this.tableLayoutPanel2.ResumeLayout(false); this.tableLayoutPanel2.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picIgnoreOverscanHelp)).EndInit(); this.flowLayoutPanel3.ResumeLayout(false); this.flowLayoutPanel3.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.picGroupBlankHelp)).EndInit(); @@ -564,5 +607,8 @@ private System.Windows.Forms.PictureBox picScaleHelp; private System.Windows.Forms.Button btnOpenFolder; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; + private System.Windows.Forms.CheckBox chkIgnoreOverscan; + private System.Windows.Forms.PictureBox picIgnoreOverscanHelp; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; } } \ No newline at end of file diff --git a/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.cs b/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.cs index 0e41eb3e..92b6bb8e 100644 --- a/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.cs +++ b/GUI.NET/Forms/HdPackEditor/frmHdPackEditor.cs @@ -40,6 +40,7 @@ namespace Mesen.GUI.Forms.HdPackEditor toolTip.SetToolTip(picFrequencyHelp, ResourceHelper.GetMessage("HdPackBuilderFrequencyHelp")); toolTip.SetToolTip(picGroupBlankHelp, ResourceHelper.GetMessage("HdPackBuilderGroupBlankHelp")); toolTip.SetToolTip(picLargeSpritesHelp, ResourceHelper.GetMessage("HdPackBuilderLargeSpritesHelp")); + toolTip.SetToolTip(picIgnoreOverscanHelp, ResourceHelper.GetMessage("HdPackBuilderIgnoreOverscanHelp")); UpdateUI(false); } @@ -149,7 +150,9 @@ namespace Mesen.GUI.Forms.HdPackEditor if(chkGroupBlankTiles.Checked) { flags |= HdPackRecordFlags.GroupBlankTiles; } - + if(chkIgnoreOverscan.Checked) { + flags |= HdPackRecordFlags.IgnoreOverscan; + } InteropEmu.HdBuilderStartRecording(txtSaveFolder.Text, ((FilterInfo)cboScale.SelectedItem).FilterType, ((FilterInfo)cboScale.SelectedItem).Scale, flags, (UInt32)Math.Pow(2, cboChrBankSize.SelectedIndex) * 0x400); tmrRefresh.Start(); diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index b529c30f..a96e07d5 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -1482,6 +1482,7 @@ namespace Mesen.GUI UseLargeSprites = 1, SortByUsageFrequency = 2, GroupBlankTiles = 4, + IgnoreOverscan = 8, } public struct AddressTypeInfo