From 41c59b164a6e8822185130deb18e8dbde459ceb8 Mon Sep 17 00:00:00 2001 From: Souryo Date: Mon, 10 Apr 2017 18:29:44 -0400 Subject: [PATCH] BPS patch support --- Core/RomLoader.cpp | 3 + GUI.NET/Dependencies/resources.en.xml | 4 +- GUI.NET/Dependencies/resources.es.xml | 6 +- GUI.NET/Dependencies/resources.fr.xml | 6 +- GUI.NET/Dependencies/resources.ja.xml | 2 +- GUI.NET/Dependencies/resources.pt.xml | 6 +- GUI.NET/Dependencies/resources.ru.xml | 2 +- GUI.NET/Dependencies/resources.uk.xml | 2 +- .../Forms/Config/frmPreferences.Designer.cs | 2 +- GUI.NET/Forms/frmMain.cs | 15 +-- Utilities/BpsPatcher.cpp | 127 ++++++++++++++++++ Utilities/BpsPatcher.h | 12 ++ Utilities/Utilities.vcxproj | 2 + Utilities/Utilities.vcxproj.filters | 25 ++-- 14 files changed, 183 insertions(+), 31 deletions(-) create mode 100644 Utilities/BpsPatcher.cpp create mode 100644 Utilities/BpsPatcher.h diff --git a/Core/RomLoader.cpp b/Core/RomLoader.cpp index cc3506b9..dd2477ba 100644 --- a/Core/RomLoader.cpp +++ b/Core/RomLoader.cpp @@ -2,6 +2,7 @@ #include "../Utilities/FolderUtilities.h" #include "../Utilities/ArchiveReader.h" #include "../Utilities/CRC32.h" +#include "../Utilities/BpsPatcher.h" #include "../Utilities/IpsPatcher.h" #include "../Utilities/UpsPatcher.h" #include "../Utilities/ZipReader.h" @@ -108,6 +109,8 @@ void RomLoader::ApplyPatch(string patchPath, vector &data) data = IpsPatcher::PatchBuffer(patchPath, data); } else if(memcmp(buffer, "UPS1", 4) == 0) { data = UpsPatcher::PatchBuffer(patchPath, data); + } else if(memcmp(buffer, "BPS1", 4) == 0) { + data = BpsPatcher::PatchBuffer(patchPath, data); } } } diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml index b5e2908c..c0b1a3d4 100644 --- a/GUI.NET/Dependencies/resources.en.xml +++ b/GUI.NET/Dependencies/resources.en.xml @@ -7,7 +7,7 @@ Avi files (*.avi)|*.avi|All Files (*.*)|*.* Palette Files (*.pal)|*.pal|All Files (*.*)|*.* All supported formats (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* - All supported formats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS Patches (*.ips, *.ups)|*.IPS;*.UPS|All (*.*)|*.* + All supported formats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* Test files (*.mtp)|*.mtp|All (*.*)|*.* All supported formats (*.cht, *.xml)|*.cht;*.xml @@ -42,7 +42,7 @@ This option allows Mesen to load HDNes-format HD packs if they are found. HD Packs should be placed in the "HdPacks" folder in a subfolder matching the name of the ROM. e.g: MyRom.nes should have their HD Pack in "HdPacks\MyRom\hires.txt". Note: Support for HD Packs is a work in progress and some limitations remain. You are running the latest version of Mesen Patch and reset the current game? - Please select a ROM matching the IPS/UPS patch file. + Please select a ROM matching the IPS/UPS/BPS patch file. Unable to download file. Check your internet connection and try again. Details: {0} Mesen could not launch because it was unable to load MesenCore.dll due to missing dependencies. Mesen was unable to start due to missing files. Error: MesenCore.dll is missing. diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml index 81f985f5..974f17e5 100644 --- a/GUI.NET/Dependencies/resources.es.xml +++ b/GUI.NET/Dependencies/resources.es.xml @@ -325,7 +325,7 @@ Pausar la emulación al finalizar el video Permitir entradas aunque Mesen esté en segundo plano Pausar la emulación aunque Mesen esté en segundo plano - Cargar los archivos IPS/UPS automáticamente + Cargar los archivos IPS/UPS/BPS automáticamente Abrir el directorio de Mesen Asociación de archivos Asociación de archivos @@ -516,7 +516,7 @@ Archivos avi (*.avi)|*.avi|Todos los archivos (*.*)|*.* Archivos pal (*.pal)|*.pal|Todos los archivos (*.*)|*.* Todos los formatos soportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES (*.nes, *.unf)|*.NES;*.UNF|Roms de Famicom Disk System (*.fds)|*.FDS|Archivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Archivos ZIP (*.zip)|*.ZIP|Archivos 7-Zip (*.7z)|*.7z|Todos los archivos (*.*)|*.* - Todos los formatos soportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES(*.nes, *.unf)|*.NES;*.UNF|Roms de Famicom Disk System (*.fds)|*.FDS|Archivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Archivos ZIP (*.zip)|*.ZIP|Archivos 7-Zip (*.7z)|*.7z|Archivos IPS/UPS (*.ips, *.ups)|*.IPS;*.UPS|Todos los archivos (*.*)|*.* + Todos los formatos soportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES(*.nes, *.unf)|*.NES;*.UNF|Roms de Famicom Disk System (*.fds)|*.FDS|Archivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Archivos ZIP (*.zip)|*.ZIP|Archivos 7-Zip (*.7z)|*.7z|Archivos IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Todos los archivos (*.*)|*.* Archivos de test (*.mtp)|*.mtp|Todos los archivos (*.*)|*.* Todos los formatos soportados (*.cht, *.xml)|*.cht;*.xml @@ -550,7 +550,7 @@ Esta opción permite los paquetes de gráficos en alta resolución de carga Mesen en el mismo formato que los del emulador HDNes. Los paquetes de alta resolución deberán ser colocados en los "HdPacks" en una subcarpeta con el nombre de la ROM. Ejemplo: Un paquete para "MiRom.nes" debe estar colocado en "HdPacks\MiRom\hires.txt". Nota: El soporte para paquetes de alta resolución aún no es perfecto - algunas limitaciones siguen presentes. 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 seleccionado. + Elija la ROM que corresponde al archivo IPS/UPS/BPS seleccionado. No se puede descargar el archivo. Compruebe su conexión a Internet e inténtelo de nuevo. Detalles del error: {0} Mesen no puede inciarse porque porque no puede cargar MesenCore.dll debido a dependencias no encontradas. Mesen no puede iniciarse debido a que faltan archivos. Error: No se encuentra el archivo MesenCore.dll. diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml index 84344de4..d5bb113b 100644 --- a/GUI.NET/Dependencies/resources.fr.xml +++ b/GUI.NET/Dependencies/resources.fr.xml @@ -327,7 +327,7 @@ Pauser l'émulation à la fin d'un film Permettre les entrées lorsque Mesen est en arrière-plan Pauser l'émulation lorsque Mesen est en arrière-plan - Charger les fichiers IPS/UPS automatiquement + Charger les fichiers IPS/UPS/BPS automatiquement Ouvrir le dossier de Mesen Associations de fichiers Associations de fichiers @@ -530,7 +530,7 @@ Fichiers avi (*.avi)|*.avi|Tous les fichiers (*.*)|*.* Fichier de palette (*.pal)|*.pal|Tous les fichiers (*.*)|*.* Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES (*.nes, *.unf)|*.NES;*.UNF|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Tous les fichiers (*.*)|*.* - Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES (*.nes, *.unf)|*.NES;*.UNF|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Fichiers IPS/UPS (*.ips, *.ups)|*.IPS;*.UPS|Tous les fichiers (*.*)|*.* + Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES (*.nes, *.unf)|*.NES;*.UNF|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Fichiers IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Tous les fichiers (*.*)|*.* Fichiers de test (*.mtp)|*.mtp|Tous les fichiers (*.*)|*.* Tous les formats supportés (*.cht, *.xml)|*.cht;*.xml @@ -565,7 +565,7 @@ Cette option permet à Mesen de charger des packages de graphiques haute-résolution dans le même format que l'émulateur HDNes. Les packages haute-résolution doivent être placés dans le dossier "HdPacks", dans un sous-dossier correspondant au nom du ROM. Exemple : Un package pour "MonRom.nes" doit être placé dans "HdPacks\MonRom\hires.txt". Note: Le support pour les packages haute-résolution n'est pas encore parfait - certaines limitations sont encore présentes. 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 choisi. + Choisissez un ROM qui correspond au fichier IPS/UPS/BPS choisi. Impossible de télécharger le fichier. Vérifier votre connexion internet et essayez à nouveau. Détails de l'erreur: {0} Mesen n'a pas été en mesure de charger le fichier MesenCore.dll, et ne peut donc pas être lancé. Mesen est incapable de démarrer puisqu'il manque des fichiers. Erreur: Le fichier MesenCore.dll est introuvable. diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml index a5bb00fe..d46687ac 100644 --- a/GUI.NET/Dependencies/resources.ja.xml +++ b/GUI.NET/Dependencies/resources.ja.xml @@ -512,7 +512,7 @@ AVIファイル (*.avi)|*.avi|すべてのファイル (*.*)|*.* パレットファイル (*.pal)|*.pal|すべてのファイル (*.*)|*.* 対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf)|*.NES;*.ZIP;*.FDS;*.7z;*.NSF;*.NSFE;*.UNF|ファミコンゲーム (*.nes, *.unf)|*.NES;*.UNF|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|NSFファイル (*.nsf, *.nsfe)|*.NSF;*.NSFE|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|すべてのファイル (*.*)|*.* - 対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|ファミコンゲーム (*.nes, *.unf)|*.NES;*.UNF|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|NSFファイル (*.nsf, *.nsfe)|*.NSF;*.NSFE|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|パッチファイル (*.ips, *.ups)|*.IPS;*.UPS|すべてのファイル (*.*)|*.* + 対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|ファミコンゲーム (*.nes, *.unf)|*.NES;*.UNF|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|NSFファイル (*.nsf, *.nsfe)|*.NSF;*.NSFE|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|パッチファイル (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|すべてのファイル (*.*)|*.* テストファイル (*.mtp)|*.mtp|すべてのファイル (*.*)|*.* 対応するすべてのファイル (*.cht, *.xml)|*.cht;*.xml diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml index b4bca61f..ece8fcc6 100644 --- a/GUI.NET/Dependencies/resources.pt.xml +++ b/GUI.NET/Dependencies/resources.pt.xml @@ -325,7 +325,7 @@ Pausar a emulação ao finalizar o vídeo Permitir inputs quando Mesen estiver em segundo plano Pausar a emulação quando Mesen estiver em segundo plano - Carregar os arquivos IPS/UPS automaticamente + Carregar os arquivos IPS/UPS/BPS automaticamente Abrir a pasta de Mesen Associação de arquivos Associação de arquivos @@ -516,7 +516,7 @@ Arquivos avi (*.avi)|*.avi|Todos os arquivos (*.*)|*.* Arquivos pal (*.pal)|*.pal|Todos os arquivos (*.*)|*.* Todos os formatos suportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES (*.nes, *.unf)|*.NES;*.UNF|Roms de Famicom Disk System (*.fds)|*.FDS|Arquivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arquivos ZIP (*.zip)|*.ZIP|Arquivos 7-Zip (*.7z)|*.7z|Todos os arquivos (*.*)|*.* - Todos os formatos suportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES(*.nes, *.unf)|*.NES;*.UNF|Roms de Famicom Disk System (*.fds)|*.FDS|Arquivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arquivos ZIP (*.zip)|*.ZIP|Arquivos 7-Zip (*.7z)|*.7z|Arquivos IPS/UPS (*.ips, *.ups)|*.IPS;*.UPS|Todos os arquivos (*.*)|*.* + Todos os formatos suportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|Roms de NES(*.nes, *.unf)|*.NES;*.UNF|Roms de Famicom Disk System (*.fds)|*.FDS|Arquivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arquivos ZIP (*.zip)|*.ZIP|Arquivos 7-Zip (*.7z)|*.7z|Arquivos IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Todos os arquivos (*.*)|*.* Arquivos de teste (*.mtp)|*.mtp|Todos os arquivos (*.*)|*.* Todos os formatos suportados (*.cht, *.xml)|*.cht;*.xml @@ -550,7 +550,7 @@ Esta opção permite os pacotes de gráficos de alta resolução sejam carregados no mesmo formato que os do emulador HDNes. Os pacotes de alta resolução devem ser colocados nos "HdPacks" em uma subpasta com o mesmo nome da ROM. Exemplo: Um pacote para "MinhaRom.nes" deve ser colocado em "HdPacks\MinhaRom\hires.txt". Nota: O suporte para os pacotes de alta resolução não é perfeito - algumas limitações seguem presentes. Já utiliza a versão mais recente do Mesen. Aplicar o patch e reiniciar o jogo? - Selecione a ROM que corresponde ao arquivo IPS/UPS selecionado. + Selecione a ROM que corresponde ao arquivo IPS/UPS/BPS selecionado. Não foi possível baixar o arquivo. Verifique sua conexão com a internet e tente de novo. Detalhes do erro: {0} Mesen não pode iniciar pois foi incapaz de carregar MesenCore.dll devido a falta de dependências. Mesen não pode iniciar devido a falta de arquivos. Erro: Não se encontra o arquivo MesenCore.dll. diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml index c98f2323..132910ca 100644 --- a/GUI.NET/Dependencies/resources.ru.xml +++ b/GUI.NET/Dependencies/resources.ru.xml @@ -520,7 +520,7 @@ Avi файлы (*.avi)|*.avi|All Files (*.*)|*.* Файлы палитры (*.pal)|*.pal|All Files (*.*)|*.* Все поддерживаемые форматы (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* - Все поддерживаемые форматы (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS Patches (*.ips, *.ups)|*.IPS;*.UPS|All (*.*)|*.* + Все поддерживаемые форматы (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* Test files (*.mtp)|*.mtp|All (*.*)|*.* Все поддерживаемые форматы (*.cht, *.xml)|*.cht;*.xml diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml index e7e4ccab..06796e17 100644 --- a/GUI.NET/Dependencies/resources.uk.xml +++ b/GUI.NET/Dependencies/resources.uk.xml @@ -519,7 +519,7 @@ Avi файли (*.avi)|*.avi|All Files (*.*)|*.* Файли палiтр (*.pal)|*.pal|All Files (*.*)|*.* Всі підтримувані формати (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* - Всі підтримувані формати (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS Patches (*.ips, *.ups)|*.IPS;*.UPS|All (*.*)|*.* + Всі підтримувані формати (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF|NES Roms (*.nes, *.unf)|*.NES;*.UNF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* Test files (*.mtp)|*.mtp|All (*.*)|*.* Всі підтримувані формати (*.cht, *.xml)|*.cht;*.xml diff --git a/GUI.NET/Forms/Config/frmPreferences.Designer.cs b/GUI.NET/Forms/Config/frmPreferences.Designer.cs index 551a7ac7..958fe9af 100644 --- a/GUI.NET/Forms/Config/frmPreferences.Designer.cs +++ b/GUI.NET/Forms/Config/frmPreferences.Designer.cs @@ -221,7 +221,7 @@ namespace Mesen.GUI.Forms.Config this.chkAutoLoadIps.Name = "chkAutoLoadIps"; this.chkAutoLoadIps.Size = new System.Drawing.Size(132, 17); this.chkAutoLoadIps.TabIndex = 9; - this.chkAutoLoadIps.Text = "Auto-load IPS/UPS patches"; + this.chkAutoLoadIps.Text = "Auto-load IPS/UPS/BPS patches"; this.chkAutoLoadIps.UseVisualStyleBackColor = true; // // flowLayoutPanel6 diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index 5223797b..fd57287a 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -485,7 +485,7 @@ namespace Mesen.GUI.Forms stream.Read(header, 0, 5); if(header[0] == 'P' && header[1] == 'A' && header[2] == 'T' && header[3] == 'C' && header[4] == 'H') { return true; - } else if(header[0] == 'U' && header[1] == 'P' && header[2] == 'S' && header[3] == '1') { + } else if((header[0] == 'U' || header[0] == 'B') && header[1] == 'P' && header[2] == 'S' && header[3] == '1') { return true; } } @@ -540,14 +540,13 @@ namespace Mesen.GUI.Forms string patchFile = patchFileToApply; if(patchFile == null) { - string ipsFile = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)) + ".ips"; - if(!File.Exists(ipsFile)) { - string upsFile = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)) + ".ups"; - if(File.Exists(upsFile)) { - patchFile = upsFile; + string[] extensions = new string[3] { ".ips", ".ups", ".bps" }; + foreach(string ext in extensions) { + string file = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)) + ext; + if(File.Exists(file)) { + patchFile = file; + break; } - } else { - patchFile = ipsFile; } } diff --git a/Utilities/BpsPatcher.cpp b/Utilities/BpsPatcher.cpp new file mode 100644 index 00000000..d75f1976 --- /dev/null +++ b/Utilities/BpsPatcher.cpp @@ -0,0 +1,127 @@ +#include "stdafx.h" +#include +#include +#include "BpsPatcher.h" +#include "CRC32.h" + +uint64_t BpsPatcher::ReadBase128Number(ifstream &file) +{ + uint64_t result = 0; + int shift = 0; + uint8_t buffer; + while(true) { + file.read((char*)&buffer, 1); + if(file.eof()) { + return -1; + } + result += (buffer & 0x7F) << shift; + shift += 7; + if(buffer & 0x80) { + break; + } + result += (uint64_t)1 << shift; + } + + return result; +} + +vector BpsPatcher::PatchBuffer(string bpsFilepath, vector input) +{ + ifstream bpsFile(bpsFilepath, std::ios::in | std::ios::binary); + + if(bpsFile) { + bpsFile.seekg(0, std::ios::end); + size_t fileSize = (size_t)bpsFile.tellg(); + bpsFile.seekg(0, std::ios::beg); + + char header[4]; + bpsFile.read((char*)&header, 4); + if(memcmp((char*)&header, "BPS1", 4) != 0) { + //Invalid BPS file + return input; + } + + uint64_t inputFileSize = ReadBase128Number(bpsFile); + uint64_t outputFileSize = ReadBase128Number(bpsFile); + if(inputFileSize == -1 || outputFileSize == -1) { + //Invalid file + return input; + } + + uint64_t metadataSize = ReadBase128Number(bpsFile); + bpsFile.seekg(metadataSize, std::ios::cur); + + vector output; + output.resize(outputFileSize); + + uint64_t outputOffset = 0; + uint64_t inputRelativeOffset = 0; + uint64_t outputRelativeOffset = 0; + while((size_t)bpsFile.tellg() < fileSize - 12) { + uint64_t data = ReadBase128Number(bpsFile); + if(data == -1) { + //Invalid file + return input; + } + + uint8_t command = data & 0x03; + uint64_t length = (data >> 2) + 1; + switch(command) { + case 0: + //SourceRead + while(length--) { + output[outputOffset] = input[outputOffset]; + outputOffset++; + } + break; + + case 1: + //TargetRead + while(length--) { + uint8_t value = 0; + bpsFile.read((char*)&value, 1); + + output[outputOffset++] = value; + } + break; + + case 2: { + //SourceCopy + uint64_t data = ReadBase128Number(bpsFile); + inputRelativeOffset += (data & 1 ? -1 : +1) * (data >> 1); + while(length--) { + output[outputOffset++] = input[inputRelativeOffset++]; + } + break; + } + + case 3: { + //TargetCopy + uint64_t data = ReadBase128Number(bpsFile); + outputRelativeOffset += (data & 1 ? -1 : +1) * (data >> 1); + while(length--) { + output[outputOffset++] = output[outputRelativeOffset++]; + } + break; + } + } + } + + uint8_t inputChecksum[4]; + uint8_t outputChecksum[4]; + bpsFile.read((char*)inputChecksum, 4); + bpsFile.read((char*)outputChecksum, 4); + uint32_t patchInputCrc = inputChecksum[0] | (inputChecksum[1] << 8) | (inputChecksum[2] << 16) | (inputChecksum[3] << 24); + uint32_t patchOutputCrc = outputChecksum[0] | (outputChecksum[1] << 8) | (outputChecksum[2] << 16) | (outputChecksum[3] << 24); + uint32_t inputCrc = CRC32::GetCRC(input.data(), input.size()); + uint32_t outputCrc = CRC32::GetCRC(output.data(), output.size()); + + if(patchInputCrc != inputCrc || patchOutputCrc != outputCrc) { + return input; + } + + bpsFile.close(); + return output; + } + return input; +} diff --git a/Utilities/BpsPatcher.h b/Utilities/BpsPatcher.h new file mode 100644 index 00000000..261be630 --- /dev/null +++ b/Utilities/BpsPatcher.h @@ -0,0 +1,12 @@ +#pragma once + +#include "stdafx.h" + +class BpsPatcher +{ +private: + static uint64_t BpsPatcher::ReadBase128Number(ifstream &file); + +public: + static vector PatchBuffer(string bpsFilepath, vector input); +}; \ No newline at end of file diff --git a/Utilities/Utilities.vcxproj b/Utilities/Utilities.vcxproj index f9577b32..09590945 100644 --- a/Utilities/Utilities.vcxproj +++ b/Utilities/Utilities.vcxproj @@ -324,6 +324,7 @@ + @@ -366,6 +367,7 @@ + diff --git a/Utilities/Utilities.vcxproj.filters b/Utilities/Utilities.vcxproj.filters index 2c0c367e..a8915fee 100644 --- a/Utilities/Utilities.vcxproj.filters +++ b/Utilities/Utilities.vcxproj.filters @@ -24,6 +24,9 @@ {8b0e23bf-1bd9-4cc1-8046-784fd01e8688} + + {6d519bc1-7c40-448a-95d2-9ad94cd20644} + @@ -71,9 +74,6 @@ Header Files - - Header Files - Header Files @@ -143,8 +143,14 @@ Header Files + + Patches + - Header Files + Patches + + + Patches @@ -190,9 +196,6 @@ Source Files - - Source Files - Source Files @@ -254,7 +257,13 @@ Avi - Source Files + Patches + + + Patches + + + Patches \ No newline at end of file