BPS patch support

This commit is contained in:
Souryo 2017-04-10 18:29:44 -04:00
parent 92107d94df
commit 41c59b164a
14 changed files with 183 additions and 31 deletions

View file

@ -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<uint8_t> &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);
}
}
}

View file

@ -7,7 +7,7 @@
<Message ID="FilterAvi">Avi files (*.avi)|*.avi|All Files (*.*)|*.*</Message>
<Message ID="FilterPalette">Palette Files (*.pal)|*.pal|All Files (*.*)|*.*</Message>
<Message ID="FilterRom">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
<Message ID="FilterCheat">All supported formats (*.cht, *.xml)|*.cht;*.xml</Message>
@ -42,7 +42,7 @@
<Message ID="HDNesTooltip">This option allows Mesen to load HDNes-format HD packs if they are found.&#xA;&#xA;HD Packs should be placed in the "HdPacks" folder in a subfolder matching the name of the ROM.&#xA;e.g: MyRom.nes should have their HD Pack in "HdPacks\MyRom\hires.txt".&#xA;&#xA;Note: Support for HD Packs is a work in progress and some limitations remain.</Message>
<Message ID="MesenUpToDate">You are running the latest version of Mesen</Message>
<Message ID="PatchAndReset">Patch and reset the current game?</Message>
<Message ID="SelectRomIps">Please select a ROM matching the IPS/UPS patch file.</Message>
<Message ID="SelectRomIps">Please select a ROM matching the IPS/UPS/BPS patch file.</Message>
<Message ID="UnableToDownload">Unable to download file. Check your internet connection and try again.&#xA;&#xA;Details:&#xA;{0}</Message>
<Message ID="UnableToStartMissingDependencies">Mesen could not launch because it was unable to load MesenCore.dll due to missing dependencies.</Message>
<Message ID="UnableToStartMissingFiles">Mesen was unable to start due to missing files.&#xA;&#xA;Error: MesenCore.dll is missing.</Message>

View file

@ -325,7 +325,7 @@
<Control ID="chkPauseOnMovieEnd">Pausar la emulación al finalizar el video</Control>
<Control ID="chkAllowBackgroundInput">Permitir entradas aunque Mesen esté en segundo plano</Control>
<Control ID="chkPauseWhenInBackground">Pausar la emulación aunque Mesen esté en segundo plano</Control>
<Control ID="chkAutoLoadIps">Cargar los archivos IPS/UPS automáticamente</Control>
<Control ID="chkAutoLoadIps">Cargar los archivos IPS/UPS/BPS automáticamente</Control>
<Control ID="btnOpenMesenFolder">Abrir el directorio de Mesen</Control>
<Control ID="tpgFileAssociations">Asociación de archivos</Control>
<Control ID="grpFileAssociations">Asociación de archivos</Control>
@ -516,7 +516,7 @@
<Message ID="FilterAvi">Archivos avi (*.avi)|*.avi|Todos los archivos (*.*)|*.*</Message>
<Message ID="FilterPalette">Archivos pal (*.pal)|*.pal|Todos los archivos (*.*)|*.*</Message>
<Message ID="FilterRom">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterTest">Archivos de test (*.mtp)|*.mtp|Todos los archivos (*.*)|*.*</Message>
<Message ID="FilterCheat">Todos los formatos soportados (*.cht, *.xml)|*.cht;*.xml</Message>
@ -550,7 +550,7 @@
<Message ID="HDNesTooltip">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.&#xA;&#xA;Los paquetes de alta resolución deberán ser colocados en los "HdPacks" en una subcarpeta con el nombre de la ROM.&#xA;Ejemplo: Un paquete para "MiRom.nes" debe estar colocado en "HdPacks\MiRom\hires.txt".&#xA;&#xA;Nota: El soporte para paquetes de alta resolución aún no es perfecto - algunas limitaciones siguen presentes.</Message>
<Message ID="MesenUpToDate">Ya utiliza la versión mas reciente de Mesen.</Message>
<Message ID="PatchAndReset">¿Aplicar el parche y reiniciar el juego?</Message>
<Message ID="SelectRomIps">Elija la ROM que corresponde al archivo IPS/UPS seleccionado.</Message>
<Message ID="SelectRomIps">Elija la ROM que corresponde al archivo IPS/UPS/BPS seleccionado.</Message>
<Message ID="UnableToDownload">No se puede descargar el archivo. Compruebe su conexión a Internet e inténtelo de nuevo.&#xA;&#xA;Detalles del error:&#xA;{0}</Message>
<Message ID="UnableToStartMissingDependencies">Mesen no puede inciarse porque porque no puede cargar MesenCore.dll debido a dependencias no encontradas.</Message>
<Message ID="UnableToStartMissingFiles">Mesen no puede iniciarse debido a que faltan archivos.&#xA;&#xA;Error: No se encuentra el archivo MesenCore.dll.</Message>

View file

@ -327,7 +327,7 @@
<Control ID="chkPauseOnMovieEnd">Pauser l'émulation à la fin d'un film</Control>
<Control ID="chkAllowBackgroundInput">Permettre les entrées lorsque Mesen est en arrière-plan</Control>
<Control ID="chkPauseWhenInBackground">Pauser l'émulation lorsque Mesen est en arrière-plan</Control>
<Control ID="chkAutoLoadIps">Charger les fichiers IPS/UPS automatiquement</Control>
<Control ID="chkAutoLoadIps">Charger les fichiers IPS/UPS/BPS automatiquement</Control>
<Control ID="btnOpenMesenFolder">Ouvrir le dossier de Mesen</Control>
<Control ID="tpgFileAssociations">Associations de fichiers</Control>
<Control ID="grpFileAssociations">Associations de fichiers</Control>
@ -530,7 +530,7 @@
<Message ID="FilterAvi">Fichiers avi (*.avi)|*.avi|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterPalette">Fichier de palette (*.pal)|*.pal|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterRom">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterTest">Fichiers de test (*.mtp)|*.mtp|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterCheat">Tous les formats supportés (*.cht, *.xml)|*.cht;*.xml</Message>
@ -565,7 +565,7 @@
<Message ID="HDNesTooltip">Cette option permet à Mesen de charger des packages de graphiques haute-résolution dans le même format que l'émulateur HDNes.&#xA;&#xA;Les packages haute-résolution doivent être placés dans le dossier "HdPacks", dans un sous-dossier correspondant au nom du ROM.&#xA;Exemple : Un package pour "MonRom.nes" doit être placé dans "HdPacks\MonRom\hires.txt".&#xA;&#xA;Note: Le support pour les packages haute-résolution n'est pas encore parfait - certaines limitations sont encore présentes.</Message>
<Message ID="MesenUpToDate">Vous utilisez déjà la version la plus récente de Mesen.</Message>
<Message ID="PatchAndReset">Appliquer la patch et faire un reset du jeu?</Message>
<Message ID="SelectRomIps">Choisissez un ROM qui correspond au fichier IPS/UPS choisi.</Message>
<Message ID="SelectRomIps">Choisissez un ROM qui correspond au fichier IPS/UPS/BPS choisi.</Message>
<Message ID="UnableToDownload">Impossible de télécharger le fichier. Vérifier votre connexion internet et essayez à nouveau.&#xA;&#xA;Détails de l'erreur:&#xA;{0}</Message>
<Message ID="UnableToStartMissingDependencies">Mesen n'a pas été en mesure de charger le fichier MesenCore.dll, et ne peut donc pas être lancé.</Message>
<Message ID="UnableToStartMissingFiles">Mesen est incapable de démarrer puisqu'il manque des fichiers.&#xA;&#xA;Erreur: Le fichier MesenCore.dll est introuvable.</Message>

View file

@ -512,7 +512,7 @@
<Message ID="FilterAvi">AVIファイル (*.avi)|*.avi|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterPalette">パレットファイル (*.pal)|*.pal|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterRom">対応するすべてのファイル (*.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|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterRomIps">対応するすべてのファイル (*.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|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterRomIps">対応するすべてのファイル (*.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|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterTest">テストファイル (*.mtp)|*.mtp|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterCheat">対応するすべてのファイル (*.cht, *.xml)|*.cht;*.xml</Message>

View file

@ -325,7 +325,7 @@
<Control ID="chkPauseOnMovieEnd">Pausar a emulação ao finalizar o vídeo</Control>
<Control ID="chkAllowBackgroundInput">Permitir inputs quando Mesen estiver em segundo plano</Control>
<Control ID="chkPauseWhenInBackground">Pausar a emulação quando Mesen estiver em segundo plano</Control>
<Control ID="chkAutoLoadIps">Carregar os arquivos IPS/UPS automaticamente</Control>
<Control ID="chkAutoLoadIps">Carregar os arquivos IPS/UPS/BPS automaticamente</Control>
<Control ID="btnOpenMesenFolder">Abrir a pasta de Mesen</Control>
<Control ID="tpgFileAssociations">Associação de arquivos</Control>
<Control ID="grpFileAssociations">Associação de arquivos</Control>
@ -516,7 +516,7 @@
<Message ID="FilterAvi">Arquivos avi (*.avi)|*.avi|Todos os arquivos (*.*)|*.*</Message>
<Message ID="FilterPalette">Arquivos pal (*.pal)|*.pal|Todos os arquivos (*.*)|*.*</Message>
<Message ID="FilterRom">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">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 (*.*)|*.*</Message>
<Message ID="FilterTest">Arquivos de teste (*.mtp)|*.mtp|Todos os arquivos (*.*)|*.*</Message>
<Message ID="FilterCheat">Todos os formatos suportados (*.cht, *.xml)|*.cht;*.xml</Message>
@ -550,7 +550,7 @@
<Message ID="HDNesTooltip">Esta opção permite os pacotes de gráficos de alta resolução sejam carregados no mesmo formato que os do emulador HDNes.&#xA;&#xA;Os pacotes de alta resolução devem ser colocados nos "HdPacks" em uma subpasta com o mesmo nome da ROM.&#xA;Exemplo: Um pacote para "MinhaRom.nes" deve ser colocado em "HdPacks\MinhaRom\hires.txt".&#xA;&#xA;Nota: O suporte para os pacotes de alta resolução não é perfeito - algumas limitações seguem presentes.</Message>
<Message ID="MesenUpToDate">Já utiliza a versão mais recente do Mesen.</Message>
<Message ID="PatchAndReset">Aplicar o patch e reiniciar o jogo?</Message>
<Message ID="SelectRomIps">Selecione a ROM que corresponde ao arquivo IPS/UPS selecionado.</Message>
<Message ID="SelectRomIps">Selecione a ROM que corresponde ao arquivo IPS/UPS/BPS selecionado.</Message>
<Message ID="UnableToDownload">Não foi possível baixar o arquivo. Verifique sua conexão com a internet e tente de novo.&#xA;&#xA;Detalhes do erro:&#xA;{0}</Message>
<Message ID="UnableToStartMissingDependencies">Mesen não pode iniciar pois foi incapaz de carregar MesenCore.dll devido a falta de dependências.</Message>
<Message ID="UnableToStartMissingFiles">Mesen não pode iniciar devido a falta de arquivos.&#xA;&#xA;Erro: Não se encontra o arquivo MesenCore.dll.</Message>

View file

@ -520,7 +520,7 @@
<Message ID="FilterAvi">Avi файлы (*.avi)|*.avi|All Files (*.*)|*.*</Message>
<Message ID="FilterPalette">Файлы палитры (*.pal)|*.pal|All Files (*.*)|*.*</Message>
<Message ID="FilterRom">Все поддерживаемые форматы (*.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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">Все поддерживаемые форматы (*.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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">Все поддерживаемые форматы (*.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 (*.*)|*.*</Message>
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
<Message ID="FilterCheat">Все поддерживаемые форматы (*.cht, *.xml)|*.cht;*.xml</Message>

View file

@ -519,7 +519,7 @@
<Message ID="FilterAvi">Avi файли (*.avi)|*.avi|All Files (*.*)|*.*</Message>
<Message ID="FilterPalette">Файли палiтр (*.pal)|*.pal|All Files (*.*)|*.*</Message>
<Message ID="FilterRom">Всі підтримувані формати (*.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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">Всі підтримувані формати (*.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 (*.*)|*.*</Message>
<Message ID="FilterRomIps">Всі підтримувані формати (*.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 (*.*)|*.*</Message>
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
<Message ID="FilterCheat">Всі підтримувані формати (*.cht, *.xml)|*.cht;*.xml</Message>

View file

@ -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

View file

@ -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;
}
}

127
Utilities/BpsPatcher.cpp Normal file
View file

@ -0,0 +1,127 @@
#include "stdafx.h"
#include <assert.h>
#include <cstring>
#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<uint8_t> BpsPatcher::PatchBuffer(string bpsFilepath, vector<uint8_t> 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<uint8_t> 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;
}

12
Utilities/BpsPatcher.h Normal file
View file

@ -0,0 +1,12 @@
#pragma once
#include "stdafx.h"
class BpsPatcher
{
private:
static uint64_t BpsPatcher::ReadBase128Number(ifstream &file);
public:
static vector<uint8_t> PatchBuffer(string bpsFilepath, vector<uint8_t> input);
};

View file

@ -324,6 +324,7 @@
<ClInclude Include="ArchiveReader.h" />
<ClInclude Include="AviWriter.h" />
<ClInclude Include="blip_buf.h" />
<ClInclude Include="BpsPatcher.h" />
<ClInclude Include="CamstudioCodec.h" />
<ClInclude Include="CRC32.h" />
<ClInclude Include="FolderUtilities.h" />
@ -366,6 +367,7 @@
<ClCompile Include="ArchiveReader.cpp" />
<ClCompile Include="AviWriter.cpp" />
<ClCompile Include="blip_buf.cpp" />
<ClCompile Include="BpsPatcher.cpp" />
<ClCompile Include="CamstudioCodec.cpp" />
<ClCompile Include="CRC32.cpp" />
<ClCompile Include="FolderUtilities.cpp" />

View file

@ -24,6 +24,9 @@
<Filter Include="Avi">
<UniqueIdentifier>{8b0e23bf-1bd9-4cc1-8046-784fd01e8688}</UniqueIdentifier>
</Filter>
<Filter Include="Patches">
<UniqueIdentifier>{6d519bc1-7c40-448a-95d2-9ad94cd20644}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -71,9 +74,6 @@
<ClInclude Include="ZipReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IpsPatcher.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LowPassFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -143,8 +143,14 @@
<ClInclude Include="StringUtilities.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IpsPatcher.h">
<Filter>Patches</Filter>
</ClInclude>
<ClInclude Include="UpsPatcher.h">
<Filter>Header Files</Filter>
<Filter>Patches</Filter>
</ClInclude>
<ClInclude Include="BpsPatcher.h">
<Filter>Patches</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -190,9 +196,6 @@
<ClCompile Include="ZipReader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IpsPatcher.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="blip_buf.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -254,7 +257,13 @@
<Filter>Avi</Filter>
</ClCompile>
<ClCompile Include="UpsPatcher.cpp">
<Filter>Source Files</Filter>
<Filter>Patches</Filter>
</ClCompile>
<ClCompile Include="IpsPatcher.cpp">
<Filter>Patches</Filter>
</ClCompile>
<ClCompile Include="BpsPatcher.cpp">
<Filter>Patches</Filter>
</ClCompile>
</ItemGroup>
</Project>