Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/hakchi2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2017-10-09 15:04:08 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2017-10-09 15:04:08 +0300
commit9e179772e5e2922566e352dc41bc1eecf1ce11bc (patch)
treead1d2361df5c4ba42b2f92124d8eae35705cb2fa
parent4b3a7c567d13bad64a55d70b4b7854a51a520be3 (diff)
Patches, better LoROM/HiROM detection, database with problem games, new mod
-rw-r--r--Apps/NesMiniApplication.cs5
-rw-r--r--Apps/SnesGame.cs234
-rw-r--r--MainForm.cs6
-rw-r--r--Program.cs1
-rw-r--r--Properties/Resources.resx7
-rw-r--r--WorkerForm.cs38
-rw-r--r--hakchi_gui.csproj141
-rw-r--r--patches/0354f4b1-Dirt Racer (Europe) (En,Fr,De).ipsbin0 -> 20 bytes
-rw-r--r--patches/09097b2b-ActRaiser (Europe).ipsbin0 -> 333 bytes
-rw-r--r--patches/0ce626ba-Hebereke's Popoitto (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/0f8378a6-Winter Gold (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/17f946c5-K.H. Rummenigge's Player Manager (Germany, Germany Sample).ipsbin0 -> 20 bytes
-rw-r--r--patches/1ac7f523-Kick Off 3 - European Challenge (Europe) (En,Fr,De,Es,It).ipsbin0 -> 20 bytes
-rw-r--r--patches/1ad61bd0-90 Minutes - European Prime Goal (Europe, Europe Beta).ipsbin0 -> 20 bytes
-rw-r--r--patches/29a78af9-ActRaiser (Germany).ipsbin0 -> 334 bytes
-rw-r--r--patches/2a9966c0-Soccer Kid (Europe) (En,Fr,De,Es,It).ipsbin0 -> 20 bytes
-rw-r--r--patches/2ae148d6-Smurfs, The (Europe) (En,Fr,De,Es,It).ipsbin0 -> 20 bytes
-rw-r--r--patches/2e9985bc-Super International Cricket (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/44a9db5c-Mega-lo-Mania (Europe) (En,Fr,De).ipsbin0 -> 20 bytes
-rw-r--r--patches/4824a630-Marko's Magic Football (Europe) (En,Fr,De,Es).ipsbin0 -> 20 bytes
-rw-r--r--patches/4ee9ee99-Castlevania - Vampire's Kiss (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/588a9707-Pop'n TwinBee (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/60b2d4a8-Striker (Europe) (En,Fr,De,Es,It,Nl,Sv).ipsbin0 -> 20 bytes
-rw-r--r--patches/630e16a1-Actraiser 2 (Europe) (En,Fr,De).ipsbin0 -> 71 bytes
-rw-r--r--patches/6d16f5e7-World Cup Striker (Europe) (En,Fr,De).ipsbin0 -> 20 bytes
-rw-r--r--patches/6f7d1745-Smash Tennis (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/797e2e82-Spirou (Europe) (En,Fr,De,Es).ipsbin0 -> 20 bytes
-rw-r--r--patches/7a313722-Hebereke's Popoon (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/7e2c7143-Lucky Luke (Europe) (En,Fr,De,Es).ipsbin0 -> 20 bytes
-rw-r--r--patches/83af6152-Asterix & Obelix (Europe) (En,Fr,De,Es).ipsbin0 -> 20 bytes
-rw-r--r--patches/8d2596a7-Manchester United Championship Soccer (Europe).ipsbin0 -> 38 bytes
-rw-r--r--patches/91a03035-Pop'n TwinBee - Rainbow Bell Adventures (Europe, Germany).ipsbin0 -> 20 bytes
-rw-r--r--patches/96dec679-Lothar Matthaeus Super Soccer (Germany).ipsbin0 -> 26 bytes
-rw-r--r--patches/974523ff-Terranigma (Europe, France, Germany, Spain).ipsbin0 -> 20 bytes
-rw-r--r--patches/9b1ea779-Fever Pitch Soccer (Europe) (En,Fr,De,Es,It).ipsbin0 -> 20 bytes
-rw-r--r--patches/a27e2664-ActRaiser (France).ipsbin0 -> 334 bytes
-rw-r--r--patches/b9d6269d-Joe & Mac 3 - Lost in the Tropics (Europe) (En,Fr,De).ipsbin0 -> 20 bytes
-rw-r--r--patches/bbcd16f4-Soccer Shootout (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/d190cf58-Eric Cantona Football Challenge (France) (En,Fr,De,Es,It,Nl,Sv).ipsbin0 -> 20 bytes
-rw-r--r--patches/d56c21a1-Donald in Maui Mallard (Europe).ipsbin0 -> 26 bytes
-rw-r--r--patches/e4925f15-Adventures of Dr. Franken, The (Europe) (En,Fr,De,Es,It,Nl,Sv).ipsbin0 -> 26 bytes
-rw-r--r--patches/f1dce2b7-Tintin in Tibet (Europe) (En,Fr,De,Nl).ipsbin0 -> 20 bytes
-rw-r--r--patches/fabff8bd-Zombies (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/fb1d16c4-Super Ice Hockey (Europe).ipsbin0 -> 20 bytes
-rw-r--r--patches/fce7bade-Kevin Keegan's Player Manager (Europe).ipsbin0 -> 20 bytes
-rw-r--r--user_mods/snes_custom_filters.hmod/canoe-custom-filters91
-rw-r--r--user_mods/snes_custom_filters.hmod/install5
-rw-r--r--user_mods/snes_custom_filters.hmod/p8030_snes_filters1
-rw-r--r--user_mods/snes_custom_filters.hmod/readme.txt14
-rw-r--r--user_mods/snes_custom_filters.hmod/uninstall2
50 files changed, 486 insertions, 59 deletions
diff --git a/Apps/NesMiniApplication.cs b/Apps/NesMiniApplication.cs
index 24d953f4..f2ad4c1b 100644
--- a/Apps/NesMiniApplication.cs
+++ b/Apps/NesMiniApplication.cs
@@ -21,6 +21,7 @@ namespace com.clusterrr.hakchi_gui
public static Image DefaultCover = Resources.blank_app;
public static Form ParentForm;
public static bool? NeedPatch;
+ public static bool? Need3rdPartyEmulator;
public static bool? NeedAutoDownloadCover;
public static string GamesDirectory
@@ -462,10 +463,10 @@ namespace com.clusterrr.hakchi_gui
if (patches.Length > 0)
patch = patches[0];
}
- var patchesPath = System.IO.Path.Combine(patchesDirectory, System.IO.Path.GetFileNameWithoutExtension(inputFileName) + ".ips");
+ var patchesPath = Path.Combine(patchesDirectory, Path.GetFileNameWithoutExtension(inputFileName) + ".ips");
if (File.Exists(patchesPath))
patch = patchesPath;
- patchesPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(inputFileName), System.IO.Path.GetFileNameWithoutExtension(inputFileName) + ".ips");
+ patchesPath = Path.Combine(Path.GetDirectoryName(inputFileName), System.IO.Path.GetFileNameWithoutExtension(inputFileName) + ".ips");
if (File.Exists(patchesPath))
patch = patchesPath;
}
diff --git a/Apps/SnesGame.cs b/Apps/SnesGame.cs
index e63e4c9c..0a52d7ca 100644
--- a/Apps/SnesGame.cs
+++ b/Apps/SnesGame.cs
@@ -20,11 +20,12 @@ namespace com.clusterrr.hakchi_gui
static List<byte> SfxTypes = new List<byte>() { 0x13, 0x14, 0x15, 0x1a };
static List<byte> Dsp1Types = new List<byte>() { 0x03, 0x05 };
static List<byte> SA1Types = new List<byte>() { 0x34, 0x35 };
+ // Known presets
static Dictionary<string, ushort> knownPresets = new Dictionary<string, ushort>()
{
{ "SUPER MARIOWORLD", 0x1011 },
{ "F-ZERO", 0x1018 },
- { "THE LEGEND OF ZELDA", 0x101D },
+ //{ "THE LEGEND OF ZELDA", 0x101D }, // Removed to use hacks and translations
{ "SUPER MARIO KART", 0x10BD },
{ "Super Metroid", 0x1040 },
{ "EARTH BOUND", 0x1070 },
@@ -43,10 +44,10 @@ namespace com.clusterrr.hakchi_gui
{ "STAR FOX", 0x1242 },
{ "YOSHI'S ISLAND", 0x123D },
{ "STARFOX2", 0x123C },
- { "ZELDANODENSETSU", 0x101F },
+ //{ "ZELDANODENSETSU", 0x101F }, // Removed to use hacks and translations
{ "SHVC FIREEMBLEM", 0x102B },
{ "SUPER DONKEY KONG", 0x1023 },
- //{ "Super Street Fighter", 0x1056 },
+ //{ "Super Street Fighter", 0x1056 }, // Invalid
{ "ROCKMAN X", 0x110A },
{ "CHOHMAKAIMURA", 0x1004 },
{ "SeikenDensetsu 2", 0x10B2 },
@@ -69,6 +70,78 @@ namespace com.clusterrr.hakchi_gui
{ "MEGAMAN X3", 0x113D },
{ "Breath of Fire", 0x1144 },
};
+ // Known LoRom games
+ static List<string> gamesLoRom = new List<string>()
+ {
+ };
+ // Known HiRom games
+ static List<string> gamesHiRom = new List<string>()
+ {
+ };
+ static List<string> problemGames = new List<string>()
+ {
+ { "ActRaiser-2 USA" }, // ActRaiser 2 (U) [!].smc
+ { "ALIEN vs. PREDATOR" }, // Alien vs. Predator (U).smc
+ { "ASTERIX" }, // Asterix (E) [!].smc
+ { "BATMAN--REVENGE JOKER" }, // Batman - Revenge of the Joker (U).smc
+ { "???????S???????????" }, // Bishoujo Senshi Sailor Moon S - Jougai Rantou! Shuyaku Soudatsusen (J).smc
+ { "CHAMPIONSHIP POOL" }, // Championship Pool (U).smc
+ { "ClayFighter 2" }, // Clay Fighter 2 - Judgment Clay (U) [!].smc
+ { "CLOCK TOWER SFX" }, // Clock Tower (J).smc
+ { "COOL WORLD" }, // Cool World (U) [!].smc
+ { "CRYSTAL BEANS" }, // Crystal Beans From Dungeon Explorer (J).smc
+ { "CYBER KNIGHT 2" }, // Cyber Knight II - Chikyuu Teikoku no Yabou (J).smc
+ { "ASCII DARK LAW" }, // Dark Law - Meaning of Death (J).smc
+ { "DIRT TRAX FX" }, // Dirt Trax FX (U) [!].smc
+ { "DBZ HYPER DIMENSION" }, // Dragon Ball Z - Hyper Dimension (F).smc
+ { "DRAGON BALL Z HD" }, // Dragon Ball Z - Hyper Dimension (J) [!].smc
+ { "DRAGONBALL Z 2" }, // Dragon Ball Z - La Legende Saien (F).smc
+ { "SFX DRAGONBALLZ2" }, // Dragon Ball Z - Super Butouden (F).smc
+ { "SFX SUPERBUTOUDEN2" }, // Dragon Ball Z - Super Butouden 2 (J) (V1.0).smc
+ { "DUNGEON MASTER" }, // Dungeon Master (U).smc
+ { "EARTHWORM JIM 2" }, // Earthworm Jim 2 (U) [!].smc
+ { "F1 WORLD CHAMP EDTION" }, // F1 World Championship Edition (E).smc
+ { "FACEBALL 2000" }, // Faceball 2000 (U) [!].smc
+ { "THE FIREMEN PAL" }, // Firemen, The (E).smc
+ { "HAMMERIN' HARRY (JPN)" }, // Ganbare Daiku no Gensan (J) [!].smc
+ { "HARMELUNNOBAIOLINHIKI" }, // Hamelin no Violin Hiki (J).smc
+ { "HOME ALONE" }, // Home Alone (U).smc
+ { "HUMAN GRANDPRIX" }, // Human Grand Prix (J).smc
+ { "HUMAN GRANDPRIX 3" }, // Human Grand Prix III - F1 Triple Battle (J).smc
+ { "ILLUSION OF GAIA USA" }, // Illusion of Gaia (U) [!].smc
+ { "ILLUSION OF TIME ENG" }, // Illusion of Time (E) [!].smc
+ { "JumpinDerby" }, // Jumpin' Derby (J).smc
+ { "KRUSTYS SUPERFUNHOUSE" }, // Krusty's Super Fun House (U) (V1.1).smc
+ { "Mario's Time Machine" }, // Mario's Time Machine (U) [!].smc
+ { "MARKOS MAGIC FOOTBALL" }, // Marko's Magic Football (E).smc
+ { "POWER RANGERS FIGHT" }, // Mighty Morphin Power Rangers - The Fighting Edition (U).smc
+ { "MOMOTETSU HAPPY" }, // Momotarou Dentetsu Happy (J) [!].smc
+ { "NHL HOCKEY 1998" }, // NHL '98 (U).smc
+ { "RENDERING RANGER R2" }, // Rendering Ranger R2 (J).smc
+ { "ROBOTREK 1 USA" }, // Robotrek (U) [!].smc
+ { "ROCK N' ROLL RACING" }, // Rock N' Roll Racing (U) [!].smc
+ { "ROMANCING SAGA3" }, // Romancing SaGa 3 (J) (V1.1).smc
+ { "SD??????GX" }, // SD Gundam GX (J) [!].smc
+ { "SECRET OF EVERMORE" }, // Secret of Evermore (U) [!].smc
+ { "Secret of MANA" }, // Secret of Mana (U) [!].smc
+ { "SIM CITY 2000" }, // Sim City 2000 (U).smc
+ { "SMASH TENNIS" }, // Smash Tennis (E) [!].smc
+ { "Star Ocean" }, // Star Ocean (J) [!].smc
+ { "STREET FIGHTER ALPHA2" }, // Street Fighter Alpha 2 (U) [!].smc
+ { "SUPER BASES LOADED 2" }, // Super Bases Loaded 2 (U).smc
+ { "PANIC BOMBER WORLD" }, // Super Bomberman - Panic Bomber W (J).smc
+ { "TALES OF PHANTASIA" }, // Tales of Phantasia (J) [!].smc
+ { "TERRANIGMA P" }, // Terranigma (E) [!].smc
+ { "TOP GEAR 3000" }, // Top Gear 3000 (U) [!].smc
+ { "UNIRACERS" }, // Uniracers (U) [!].smc
+ { "WARIO'S WOODS" }, // Wario's Woods (U) [!].smc
+ { "WORLD CLASS RUGBY" }, // World Class Rugby (E) [!].smc
+ { "WORLD CUP STRIKER" }, // World Cup Striker (E) (M3) [!].smc
+ { "WORLD MASTERS GOLF" }, // World Masters Golf (E).smc
+ { "WWF SUPER WRESTLEMANI" }, // WWF Super WrestleMania (U) [!].smc
+ { "WRESTLEMANIA" }, // WWF WrestleMania - The Arcade Game (U) [!].smc
+ };
+
private static Dictionary<uint, CachedGameInfo> gameInfoCache = null;
public override string GoogleSuffix
@@ -105,8 +178,31 @@ namespace com.clusterrr.hakchi_gui
if (ext.ToLower() != ".sfrom") // Need to patch for canoe
{
Debug.WriteLine($"Trying to convert {inputFileName}");
- MakeSfrom(ref rawRomData, ref saveCount);
+ bool problemGame = false;
+ MakeSfrom(ref rawRomData, ref saveCount, out problemGame);
outputFileName = Path.GetFileNameWithoutExtension(outputFileName) + ".sfrom";
+ // Using 3rd party emulator for this ROM
+ if (problemGame && Need3rdPartyEmulator != true)
+ {
+ if (Need3rdPartyEmulator != false)
+ {
+ var r = WorkerForm.MessageBoxFromThread(ParentForm,
+ string.Format(Resources.Need3rdPartyEmulator, Path.GetFileName(inputFileName)),
+ Resources.AreYouSure,
+ MessageBoxButtons.AbortRetryIgnore,
+ MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, true);
+ if (r == DialogResult.Abort)
+ Need3rdPartyEmulator = true;
+ if (r == DialogResult.Ignore)
+ problemGame = false;
+ }
+ else problemGame = false;
+ }
+ if (problemGame)
+ {
+ application = "/bin/snes";
+ args = "";
+ }
}
}
else
@@ -117,51 +213,78 @@ namespace com.clusterrr.hakchi_gui
return true;
}
- private static void MakeSfrom(ref byte[] rawRomData, ref byte saveCount)
+ private static SnesRomHeader GetCorrectHeader(byte[] rawRomData, out SnesRomType romType, out string gameTitle)
{
var romHeaderLoRom = SnesRomHeader.Read(rawRomData, 0x7FC0);
var romHeaderHiRom = SnesRomHeader.Read(rawRomData, 0xFFC0);
- SnesRomHeader romHeader;
- bool loRom = true;
- bool hiRom = true;
- if (romHeaderLoRom.GameTitle.Length == 0)
- loRom = false;
- foreach (char c in romHeaderLoRom.GameTitle)
- if (c < 31 || c > 127) loRom = false;
- if (romHeaderHiRom.GameTitle.Length == 0)
- hiRom = false;
- foreach (char c in romHeaderHiRom.GameTitle)
- if (c < 31 || c > 127) hiRom = false;
- SnesRomType romType;
- if (loRom && !hiRom)
- {
+ var titleLo = romHeaderLoRom.GameTitle;
+ var titleHi = romHeaderHiRom.GameTitle;
+
+ // Boring LoRom/HiRom detection...
+ if (((romHeaderLoRom.Checksum ^ 0xFFFF) == romHeaderLoRom.ChecksumComplement) &&
+ ((romHeaderHiRom.Checksum ^ 0xFFFF) != romHeaderHiRom.ChecksumComplement))
romType = SnesRomType.LoRom;
- romHeader = romHeaderLoRom;
- }
- else if (!loRom && hiRom)
- {
+ else if (((romHeaderLoRom.Checksum ^ 0xFFFF) != romHeaderLoRom.ChecksumComplement) &&
+ ((romHeaderHiRom.Checksum ^ 0xFFFF) == romHeaderHiRom.ChecksumComplement))
romType = SnesRomType.HiRom;
- romHeader = romHeaderHiRom;
- }
- else if (((romHeaderLoRom.RomMakeup & 1) == 0) && ((romHeaderHiRom.RomMakeup & 1) == 0))
- {
+ else if (titleLo.Length != 0 && titleHi.Length == 0)
romType = SnesRomType.LoRom;
- romHeader = romHeaderLoRom;
+ else if (titleLo.Length == 0 && titleHi.Length != 0)
+ romType = SnesRomType.HiRom;
+ else if ((titleLo == titleHi) && ((romHeaderLoRom.RomMakeup & 1) == 0))
+ romType = SnesRomType.LoRom;
+ else if ((titleLo == titleHi) && ((romHeaderHiRom.RomMakeup & 1) == 1))
+ romType = SnesRomType.HiRom;
+ else if (gamesLoRom.Contains(titleLo))
+ romType = SnesRomType.LoRom;
+ else if (gamesHiRom.Contains(titleHi))
+ romType = SnesRomType.HiRom;
+ else
+ {
+ bool loRom = true;
+ bool hiRom = true;
+ foreach (char c in titleLo)
+ if (c < 31 || c > 127) loRom = false;
+ foreach (char c in titleHi)
+ if (c < 31 || c > 127) hiRom = false;
+ if (loRom && !hiRom)
+ romType = SnesRomType.LoRom;
+ else if (!loRom && hiRom)
+ romType = SnesRomType.HiRom;
+ else
+ {
+ Debug.WriteLine("Can't detect ROM type");
+ throw new Exception("can't detect ROM type, seems like ROM is corrupted");
+ }
}
- else if (((romHeaderLoRom.RomMakeup & 1) == 1) && ((romHeaderHiRom.RomMakeup & 1) == 1))
+
+ SnesRomHeader romHeader;
+ if (romType == SnesRomType.LoRom)
{
- romType = SnesRomType.HiRom;
- romHeader = romHeaderHiRom;
+ romHeader = romHeaderLoRom;
+ gameTitle = titleLo;
}
else
{
- // WTF is it?
- romType = SnesRomType.HiRom;
romHeader = romHeaderHiRom;
+ gameTitle = titleHi;
}
+ return romHeader;
+ }
+
+ private static void MakeSfrom(ref byte[] rawRomData, ref byte saveCount, out bool problemGame)
+ {
+ SnesRomType romType;
+ string gameTitle;
+ SnesRomHeader romHeader = GetCorrectHeader(rawRomData, out romType, out gameTitle);
+
+ if (romType == SnesRomType.LoRom)
+ rawRomData[0x7FD9] = 0x01; // Force NTSC
+ else
+ rawRomData[0xFFD9] = 0x01; // Force NTSC
- string gameTitle = romHeader.GameTitle.Trim();
Debug.WriteLine($"Game title: {gameTitle}");
+ Debug.WriteLine($"ROM type: {romType}");
ushort presetId = 0; // 0x1011;
ushort chip = 0;
if (SfxTypes.Contains(romHeader.RomType)) // Super FX chip
@@ -181,7 +304,8 @@ namespace com.clusterrr.hakchi_gui
Debug.WriteLine($"SA1 chip detected");
presetId = 0x109C; // ID from Super Mario RPG, SA1
}
- } else
+ }
+ else
{
Debug.WriteLine($"We have preset for this game");
}
@@ -198,6 +322,10 @@ namespace com.clusterrr.hakchi_gui
if (romHeader.SramSize > 0)
saveCount = 3;
+ else
+ saveCount = 0;
+
+ problemGame = problemGames.Contains(gameTitle);
rawRomData = result;
}
@@ -256,8 +384,8 @@ namespace com.clusterrr.hakchi_gui
[StructLayout(LayoutKind.Sequential)]
private struct SnesRomHeader
{
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
- public string GameTitle;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
+ public byte[] GameTitleArr;
[MarshalAs(UnmanagedType.U1)] // $xFD5
public byte RomMakeup;
[MarshalAs(UnmanagedType.U1)] // $xFD6
@@ -266,8 +394,10 @@ namespace com.clusterrr.hakchi_gui
public byte RomSize;
[MarshalAs(UnmanagedType.U1)] // $xFD8
public byte SramSize;
- [MarshalAs(UnmanagedType.U2)] // $xFD9
- public ushort LicenseId;
+ [MarshalAs(UnmanagedType.U1)] // $xFD9
+ public byte Country;
+ [MarshalAs(UnmanagedType.U1)] // $xFDA
+ public byte License;
[MarshalAs(UnmanagedType.U1)] // $xFDB
public byte Version;
[MarshalAs(UnmanagedType.U2)] // $xFDC
@@ -275,6 +405,23 @@ namespace com.clusterrr.hakchi_gui
[MarshalAs(UnmanagedType.U2)] // $xFDE
public ushort Checksum;
+ public string GameTitle
+ {
+ get
+ {
+ var data = new List<byte>(GameTitleArr);
+ if (data.Contains(0))
+ return "";
+ if (data.Contains(0xFF))
+ return "";
+ if (data[0] == 0x20)
+ return "";
+ while (data.Count > 0 && data[data.Count - 1] == 0x20)
+ data.RemoveAt(data.Count - 1);
+ return Encoding.ASCII.GetString(data.ToArray());
+ }
+ }
+
public byte[] GetBytes()
{
int size = Marshal.SizeOf(this);
@@ -518,13 +665,16 @@ namespace com.clusterrr.hakchi_gui
CachedGameInfo gameinfo;
if (gameInfoCache != null && gameInfoCache.TryGetValue(crc32, out gameinfo))
{
- Name = gameinfo.Name;
+ if (!string.IsNullOrEmpty(gameinfo.Name))
+ Name = gameinfo.Name;
Players = gameinfo.Players;
Simultaneous = gameinfo.Simultaneous;
- ReleaseDate = gameinfo.ReleaseDate;
+ if (!string.IsNullOrEmpty(gameinfo.ReleaseDate))
+ ReleaseDate = gameinfo.ReleaseDate;
if (ReleaseDate.Length == 4) ReleaseDate += "-01";
if (ReleaseDate.Length == 7) ReleaseDate += "-01";
- Publisher = gameinfo.Publisher.ToUpper();
+ if (!string.IsNullOrEmpty(gameinfo.Publisher))
+ Publisher = gameinfo.Publisher.ToUpper();
/*
if (!string.IsNullOrEmpty(gameinfo.CoverUrl))
diff --git a/MainForm.cs b/MainForm.cs
index a10b69f0..014fd492 100644
--- a/MainForm.cs
+++ b/MainForm.cs
@@ -1255,6 +1255,11 @@ namespace com.clusterrr.hakchi_gui
upABStartOnSecondControllerToolStripMenuItem.Checked = ConfigIni.FcStart && upABStartOnSecondControllerToolStripMenuItem.Enabled;
compressGamesToolStripMenuItem.Checked = ConfigIni.Compress;
+ // Reset known free space
+ WorkerForm.NandCTotal = WorkerForm.NandCFree = WorkerForm.NandCUsed = 0;
+ if (Clovershell != null && Clovershell.IsOnline)
+ new Thread(Clovershell_OnConnected).Start();
+
LoadHidden();
LoadGames();
lastConsoleType = ConfigIni.ConsoleType;
@@ -1362,6 +1367,7 @@ namespace com.clusterrr.hakchi_gui
private void dragDrop(object sender, DragEventArgs e)
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
+ if (files == null) return;
// Need to determine type of files
// Maybe it's cover art?
diff --git a/Program.cs b/Program.cs
index a59366c6..bca5025b 100644
--- a/Program.cs
+++ b/Program.cs
@@ -71,6 +71,7 @@ namespace com.clusterrr.hakchi_gui
Debug.AutoFlush = true;
#endif
+
try
{
bool createdNew = true;
diff --git a/Properties/Resources.resx b/Properties/Resources.resx
index 45f569bf..761fc05c 100644
--- a/Properties/Resources.resx
+++ b/Properties/Resources.resx
@@ -181,7 +181,7 @@
<value>Invalid kernel size:</value>
</data>
<data name="MapperNotSupported" xml:space="preserve">
- <value>Sorry, "{0}" uses mapper #{1} but this mapper is not supported by the NES Mini and the game will probably not start with the default emulator. But it should work if other emulator's module installed. Do you want to add this game?</value>
+ <value>"{0}" uses mapper #{1} but this mapper is not supported by the NES Mini and the game will probably not start with the default emulator. But it should work if other emulator's module installed. Do you want to add this game?</value>
</data>
<data name="MD5Failed" xml:space="preserve">
<value>Kernel dumped but the MD5 checksum is unknown:</value>
@@ -253,7 +253,7 @@
<value>Do you really want to delete the "{0}" preset?</value>
</data>
<data name="FourScreenNotSupported" xml:space="preserve">
- <value>Sorry, {0} uses four-screen mode (i.e. the game has additional VRAM memory in the cartridge), and this feature is not supported by the NES Mini. The game will probably not start. But it should work if other emulator's module installed. Do you want to add this game anyway?</value>
+ <value>Oops, {0} uses four-screen mode (i.e. the game has additional VRAM memory in the cartridge), and this feature is not supported by the NES Mini. The game will probably not start. But it should work if other emulator's module installed. Do you want to add this game anyway?</value>
</data>
<data name="InputPreset" xml:space="preserve">
<value>Please input a preset name for the current games selection.</value>
@@ -691,4 +691,7 @@
<data name="DownloadCoverQ" xml:space="preserve">
<value>Do you want to try to download box art for "{0}"?</value>
</data>
+ <data name="Need3rdPartyEmulator" xml:space="preserve">
+ <value>Oops, it seems like "{0}" is not going not work correctly with the original emulator. Do you want to use a 3rd party emulator for this game (it needs to be installed)?</value>
+ </data>
</root> \ No newline at end of file
diff --git a/WorkerForm.cs b/WorkerForm.cs
index 9b3dec83..07ae772c 100644
--- a/WorkerForm.cs
+++ b/WorkerForm.cs
@@ -83,7 +83,22 @@ namespace com.clusterrr.hakchi_gui
string selectedFile = null;
public NesMiniApplication[] addedApplications;
public static int NandCTotal, NandCUsed, NandCFree, WritedGamesSize, SaveStatesSize;
- public const long ReservedMemory = 10;
+ public static long ReservedMemory
+ {
+ get
+ {
+ switch (ConfigIni.ConsoleType)
+ {
+ default:
+ case MainForm.ConsoleType.NES:
+ case MainForm.ConsoleType.Famicom:
+ return 10;
+ case MainForm.ConsoleType.SNES:
+ case MainForm.ConsoleType.SuperFamicom:
+ return 10;
+ }
+ }
+ }
public WorkerForm(MainForm parentForm)
{
@@ -137,7 +152,7 @@ namespace com.clusterrr.hakchi_gui
"c3378edfc1b96a5268a066d5fbe12d89", // Super Famicom Mini (JAP)
};
correctKeys[MainForm.ConsoleType.NES] =
- correctKeys[MainForm.ConsoleType.Famicom] =
+ correctKeys[MainForm.ConsoleType.Famicom] =
new string[] { "bb8f49e0ae5acc8d5f9b7fa40efbd3e7" };
correctKeys[MainForm.ConsoleType.SNES] =
correctKeys[MainForm.ConsoleType.SuperFamicom] =
@@ -348,14 +363,14 @@ namespace com.clusterrr.hakchi_gui
catch { }
}
- void ShowError(Exception ex, bool dontStop = false)
+ void ShowError(Exception ex, bool dontStop = false, string prefix = null)
{
if (Disposing) return;
try
{
if (InvokeRequired)
{
- Invoke(new Action<Exception, bool>(ShowError), new object[] { ex, dontStop });
+ Invoke(new Action<Exception, bool, string>(ShowError), new object[] { ex, dontStop, prefix });
return;
}
TaskbarProgress.SetState(this, TaskbarProgress.TaskbarStates.Error);
@@ -367,7 +382,7 @@ namespace com.clusterrr.hakchi_gui
//if (ex is MadWizard.WinUSBNet.USBException) // TODO
// MessageBox.Show(this, message + "\r\n" + Resources.PleaseTryAgainUSB, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
//else
- MessageBox.Show(this, message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBox.Show(this, (!string.IsNullOrEmpty(prefix) ? (prefix + ": ") : "") + message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
TaskbarProgress.SetState(this, TaskbarProgress.TaskbarStates.Normal);
if (!dontStop)
{
@@ -1266,6 +1281,7 @@ namespace com.clusterrr.hakchi_gui
addedApplications = null;
NesMiniApplication.ParentForm = this;
NesMiniApplication.NeedPatch = null;
+ NesMiniApplication.Need3rdPartyEmulator = null;
NesGame.IgnoreMapper = null;
SnesGame.NeedAutoDownloadCover = null;
int count = 0;
@@ -1361,8 +1377,16 @@ namespace com.clusterrr.hakchi_gui
catch (Exception ex)
{
if (ex is ThreadAbortException) return null;
- Debug.WriteLine(ex.Message + ex.StackTrace);
- ShowError(ex, true);
+ if (ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message))
+ {
+ Debug.WriteLine(ex.InnerException.Message + ex.InnerException.StackTrace);
+ ShowError(ex.InnerException, true, Path.GetFileName(sourceFileName));
+ }
+ else
+ {
+ Debug.WriteLine(ex.Message + ex.StackTrace);
+ ShowError(ex, true, Path.GetFileName(sourceFileName));
+ }
}
if (app != null)
apps.Add(app);
diff --git a/hakchi_gui.csproj b/hakchi_gui.csproj
index 8d17953b..b6bfc2fa 100644
--- a/hakchi_gui.csproj
+++ b/hakchi_gui.csproj
@@ -596,6 +596,9 @@
<Compile Include="WorkerForm.Designer.cs">
<DependentUpon>WorkerForm.cs</DependentUpon>
</Compile>
+ <Content Include="user_mods\snes_custom_filters.hmod\readme.txt">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
<EmbeddedResource Include="AboutBox.resx">
<DependentUpon>AboutBox.cs</DependentUpon>
</EmbeddedResource>
@@ -1917,7 +1920,133 @@
<Content Include="mods\mod_hakchi\hakchi\rootfs\bin\usleep">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
+ <Content Include="patches\0354f4b1-Dirt Racer %28Europe%29 %28En,Fr,De%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\09097b2b-ActRaiser %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\0ce626ba-Hebereke%27s Popoitto %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\0f8378a6-Winter Gold %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\17f946c5-K.H. Rummenigge%27s Player Manager %28Germany, Germany Sample%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\1ac7f523-Kick Off 3 - European Challenge %28Europe%29 %28En,Fr,De,Es,It%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\1ad61bd0-90 Minutes - European Prime Goal %28Europe, Europe Beta%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\29a78af9-ActRaiser %28Germany%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\2a9966c0-Soccer Kid %28Europe%29 %28En,Fr,De,Es,It%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\2ae148d6-Smurfs, The %28Europe%29 %28En,Fr,De,Es,It%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\2e9985bc-Super International Cricket %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\44a9db5c-Mega-lo-Mania %28Europe%29 %28En,Fr,De%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\4ee9ee99-Castlevania - Vampire%27s Kiss %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\588a9707-Pop%27n TwinBee %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\60b2d4a8-Striker %28Europe%29 %28En,Fr,De,Es,It,Nl,Sv%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\630e16a1-Actraiser 2 %28Europe%29 %28En,Fr,De%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\797e2e82-Spirou %28Europe%29 %28En,Fr,De,Es%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\7a313722-Hebereke%27s Popoon %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\7e2c7143-Lucky Luke %28Europe%29 %28En,Fr,De,Es%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\83af6152-Asterix &amp; Obelix %28Europe%29 %28En,Fr,De,Es%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\8d2596a7-Manchester United Championship Soccer %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\91a03035-Pop%27n TwinBee - Rainbow Bell Adventures %28Europe, Germany%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\96dec679-Lothar Matthaeus Super Soccer %28Germany%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\9b1ea779-Fever Pitch Soccer %28Europe%29 %28En,Fr,De,Es,It%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\a27e2664-ActRaiser %28France%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\b9d6269d-Joe &amp; Mac 3 - Lost in the Tropics %28Europe%29 %28En,Fr,De%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\bbcd16f4-Soccer Shootout %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\d190cf58-Eric Cantona Football Challenge %28France%29 %28En,Fr,De,Es,It,Nl,Sv%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\d56c21a1-Donald in Maui Mallard %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\e4925f15-Adventures of Dr. Franken, The %28Europe%29 %28En,Fr,De,Es,It,Nl,Sv%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\f1dce2b7-Tintin in Tibet %28Europe%29 %28En,Fr,De,Nl%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\fabff8bd-Zombies %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\fb1d16c4-Super Ice Hockey %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\fce7bade-Kevin Keegan%27s Player Manager %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\4824a630-Marko%27s Magic Football %28Europe%29 %28En,Fr,De,Es%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\6d16f5e7-World Cup Striker %28Europe%29 %28En,Fr,De%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\6f7d1745-Smash Tennis %28Europe%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="patches\974523ff-Terranigma %28Europe, France, Germany, Spain%29.ips">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
<None Include="Properties\app.manifest" />
+ <Content Include="user_mods\snes_custom_filters.hmod\canoe-custom-filters">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="user_mods\snes_custom_filters.hmod\install">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="user_mods\snes_custom_filters.hmod\p8030_snes_filters">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="user_mods\snes_custom_filters.hmod\uninstall">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
<ItemGroup>
<Content Include="data\GameGenieDB.xml">
@@ -2305,32 +2434,32 @@
<ItemGroup>
<PublishFile Include="data\GameGenieDB.xml">
<Visible>False</Visible>
+ <PublishState>Include</PublishState>
+ <IncludeHash>True</IncludeHash>
<Group>
</Group>
<TargetPath>
</TargetPath>
- <PublishState>Include</PublishState>
- <IncludeHash>True</IncludeHash>
<FileType>File</FileType>
</PublishFile>
<PublishFile Include="data\nescarts.xml">
<Visible>False</Visible>
+ <PublishState>Include</PublishState>
+ <IncludeHash>True</IncludeHash>
<Group>
</Group>
<TargetPath>
</TargetPath>
- <PublishState>Include</PublishState>
- <IncludeHash>True</IncludeHash>
<FileType>File</FileType>
</PublishFile>
<PublishFile Include="data\snescarts.xml">
<Visible>False</Visible>
+ <PublishState>Include</PublishState>
+ <IncludeHash>True</IncludeHash>
<Group>
</Group>
<TargetPath>
</TargetPath>
- <PublishState>Include</PublishState>
- <IncludeHash>True</IncludeHash>
<FileType>File</FileType>
</PublishFile>
</ItemGroup>
diff --git a/patches/0354f4b1-Dirt Racer (Europe) (En,Fr,De).ips b/patches/0354f4b1-Dirt Racer (Europe) (En,Fr,De).ips
new file mode 100644
index 00000000..659f1e9e
--- /dev/null
+++ b/patches/0354f4b1-Dirt Racer (Europe) (En,Fr,De).ips
Binary files differ
diff --git a/patches/09097b2b-ActRaiser (Europe).ips b/patches/09097b2b-ActRaiser (Europe).ips
new file mode 100644
index 00000000..4572b1b8
--- /dev/null
+++ b/patches/09097b2b-ActRaiser (Europe).ips
Binary files differ
diff --git a/patches/0ce626ba-Hebereke's Popoitto (Europe).ips b/patches/0ce626ba-Hebereke's Popoitto (Europe).ips
new file mode 100644
index 00000000..3e803995
--- /dev/null
+++ b/patches/0ce626ba-Hebereke's Popoitto (Europe).ips
Binary files differ
diff --git a/patches/0f8378a6-Winter Gold (Europe).ips b/patches/0f8378a6-Winter Gold (Europe).ips
new file mode 100644
index 00000000..f79fd856
--- /dev/null
+++ b/patches/0f8378a6-Winter Gold (Europe).ips
Binary files differ
diff --git a/patches/17f946c5-K.H. Rummenigge's Player Manager (Germany, Germany Sample).ips b/patches/17f946c5-K.H. Rummenigge's Player Manager (Germany, Germany Sample).ips
new file mode 100644
index 00000000..3f2fda55
--- /dev/null
+++ b/patches/17f946c5-K.H. Rummenigge's Player Manager (Germany, Germany Sample).ips
Binary files differ
diff --git a/patches/1ac7f523-Kick Off 3 - European Challenge (Europe) (En,Fr,De,Es,It).ips b/patches/1ac7f523-Kick Off 3 - European Challenge (Europe) (En,Fr,De,Es,It).ips
new file mode 100644
index 00000000..3e849839
--- /dev/null
+++ b/patches/1ac7f523-Kick Off 3 - European Challenge (Europe) (En,Fr,De,Es,It).ips
Binary files differ
diff --git a/patches/1ad61bd0-90 Minutes - European Prime Goal (Europe, Europe Beta).ips b/patches/1ad61bd0-90 Minutes - European Prime Goal (Europe, Europe Beta).ips
new file mode 100644
index 00000000..a936f076
--- /dev/null
+++ b/patches/1ad61bd0-90 Minutes - European Prime Goal (Europe, Europe Beta).ips
Binary files differ
diff --git a/patches/29a78af9-ActRaiser (Germany).ips b/patches/29a78af9-ActRaiser (Germany).ips
new file mode 100644
index 00000000..d36c3abd
--- /dev/null
+++ b/patches/29a78af9-ActRaiser (Germany).ips
Binary files differ
diff --git a/patches/2a9966c0-Soccer Kid (Europe) (En,Fr,De,Es,It).ips b/patches/2a9966c0-Soccer Kid (Europe) (En,Fr,De,Es,It).ips
new file mode 100644
index 00000000..05eecb0d
--- /dev/null
+++ b/patches/2a9966c0-Soccer Kid (Europe) (En,Fr,De,Es,It).ips
Binary files differ
diff --git a/patches/2ae148d6-Smurfs, The (Europe) (En,Fr,De,Es,It).ips b/patches/2ae148d6-Smurfs, The (Europe) (En,Fr,De,Es,It).ips
new file mode 100644
index 00000000..e0b6953f
--- /dev/null
+++ b/patches/2ae148d6-Smurfs, The (Europe) (En,Fr,De,Es,It).ips
Binary files differ
diff --git a/patches/2e9985bc-Super International Cricket (Europe).ips b/patches/2e9985bc-Super International Cricket (Europe).ips
new file mode 100644
index 00000000..5f915591
--- /dev/null
+++ b/patches/2e9985bc-Super International Cricket (Europe).ips
Binary files differ
diff --git a/patches/44a9db5c-Mega-lo-Mania (Europe) (En,Fr,De).ips b/patches/44a9db5c-Mega-lo-Mania (Europe) (En,Fr,De).ips
new file mode 100644
index 00000000..c95c18a9
--- /dev/null
+++ b/patches/44a9db5c-Mega-lo-Mania (Europe) (En,Fr,De).ips
Binary files differ
diff --git a/patches/4824a630-Marko's Magic Football (Europe) (En,Fr,De,Es).ips b/patches/4824a630-Marko's Magic Football (Europe) (En,Fr,De,Es).ips
new file mode 100644
index 00000000..0cf4a07b
--- /dev/null
+++ b/patches/4824a630-Marko's Magic Football (Europe) (En,Fr,De,Es).ips
Binary files differ
diff --git a/patches/4ee9ee99-Castlevania - Vampire's Kiss (Europe).ips b/patches/4ee9ee99-Castlevania - Vampire's Kiss (Europe).ips
new file mode 100644
index 00000000..1354e388
--- /dev/null
+++ b/patches/4ee9ee99-Castlevania - Vampire's Kiss (Europe).ips
Binary files differ
diff --git a/patches/588a9707-Pop'n TwinBee (Europe).ips b/patches/588a9707-Pop'n TwinBee (Europe).ips
new file mode 100644
index 00000000..494673a4
--- /dev/null
+++ b/patches/588a9707-Pop'n TwinBee (Europe).ips
Binary files differ
diff --git a/patches/60b2d4a8-Striker (Europe) (En,Fr,De,Es,It,Nl,Sv).ips b/patches/60b2d4a8-Striker (Europe) (En,Fr,De,Es,It,Nl,Sv).ips
new file mode 100644
index 00000000..872af409
--- /dev/null
+++ b/patches/60b2d4a8-Striker (Europe) (En,Fr,De,Es,It,Nl,Sv).ips
Binary files differ
diff --git a/patches/630e16a1-Actraiser 2 (Europe) (En,Fr,De).ips b/patches/630e16a1-Actraiser 2 (Europe) (En,Fr,De).ips
new file mode 100644
index 00000000..13ec8fe1
--- /dev/null
+++ b/patches/630e16a1-Actraiser 2 (Europe) (En,Fr,De).ips
Binary files differ
diff --git a/patches/6d16f5e7-World Cup Striker (Europe) (En,Fr,De).ips b/patches/6d16f5e7-World Cup Striker (Europe) (En,Fr,De).ips
new file mode 100644
index 00000000..8cdde3ca
--- /dev/null
+++ b/patches/6d16f5e7-World Cup Striker (Europe) (En,Fr,De).ips
Binary files differ
diff --git a/patches/6f7d1745-Smash Tennis (Europe).ips b/patches/6f7d1745-Smash Tennis (Europe).ips
new file mode 100644
index 00000000..9bbbab56
--- /dev/null
+++ b/patches/6f7d1745-Smash Tennis (Europe).ips
Binary files differ
diff --git a/patches/797e2e82-Spirou (Europe) (En,Fr,De,Es).ips b/patches/797e2e82-Spirou (Europe) (En,Fr,De,Es).ips
new file mode 100644
index 00000000..81ba8414
--- /dev/null
+++ b/patches/797e2e82-Spirou (Europe) (En,Fr,De,Es).ips
Binary files differ
diff --git a/patches/7a313722-Hebereke's Popoon (Europe).ips b/patches/7a313722-Hebereke's Popoon (Europe).ips
new file mode 100644
index 00000000..e58491c2
--- /dev/null
+++ b/patches/7a313722-Hebereke's Popoon (Europe).ips
Binary files differ
diff --git a/patches/7e2c7143-Lucky Luke (Europe) (En,Fr,De,Es).ips b/patches/7e2c7143-Lucky Luke (Europe) (En,Fr,De,Es).ips
new file mode 100644
index 00000000..ad7c11de
--- /dev/null
+++ b/patches/7e2c7143-Lucky Luke (Europe) (En,Fr,De,Es).ips
Binary files differ
diff --git a/patches/83af6152-Asterix & Obelix (Europe) (En,Fr,De,Es).ips b/patches/83af6152-Asterix & Obelix (Europe) (En,Fr,De,Es).ips
new file mode 100644
index 00000000..e0ac106a
--- /dev/null
+++ b/patches/83af6152-Asterix & Obelix (Europe) (En,Fr,De,Es).ips
Binary files differ
diff --git a/patches/8d2596a7-Manchester United Championship Soccer (Europe).ips b/patches/8d2596a7-Manchester United Championship Soccer (Europe).ips
new file mode 100644
index 00000000..c6b6e202
--- /dev/null
+++ b/patches/8d2596a7-Manchester United Championship Soccer (Europe).ips
Binary files differ
diff --git a/patches/91a03035-Pop'n TwinBee - Rainbow Bell Adventures (Europe, Germany).ips b/patches/91a03035-Pop'n TwinBee - Rainbow Bell Adventures (Europe, Germany).ips
new file mode 100644
index 00000000..30282d38
--- /dev/null
+++ b/patches/91a03035-Pop'n TwinBee - Rainbow Bell Adventures (Europe, Germany).ips
Binary files differ
diff --git a/patches/96dec679-Lothar Matthaeus Super Soccer (Germany).ips b/patches/96dec679-Lothar Matthaeus Super Soccer (Germany).ips
new file mode 100644
index 00000000..18d77af9
--- /dev/null
+++ b/patches/96dec679-Lothar Matthaeus Super Soccer (Germany).ips
Binary files differ
diff --git a/patches/974523ff-Terranigma (Europe, France, Germany, Spain).ips b/patches/974523ff-Terranigma (Europe, France, Germany, Spain).ips
new file mode 100644
index 00000000..58c8c993
--- /dev/null
+++ b/patches/974523ff-Terranigma (Europe, France, Germany, Spain).ips
Binary files differ
diff --git a/patches/9b1ea779-Fever Pitch Soccer (Europe) (En,Fr,De,Es,It).ips b/patches/9b1ea779-Fever Pitch Soccer (Europe) (En,Fr,De,Es,It).ips
new file mode 100644
index 00000000..43de1ae6
--- /dev/null
+++ b/patches/9b1ea779-Fever Pitch Soccer (Europe) (En,Fr,De,Es,It).ips
Binary files differ
diff --git a/patches/a27e2664-ActRaiser (France).ips b/patches/a27e2664-ActRaiser (France).ips
new file mode 100644
index 00000000..a53facbd
--- /dev/null
+++ b/patches/a27e2664-ActRaiser (France).ips
Binary files differ
diff --git a/patches/b9d6269d-Joe & Mac 3 - Lost in the Tropics (Europe) (En,Fr,De).ips b/patches/b9d6269d-Joe & Mac 3 - Lost in the Tropics (Europe) (En,Fr,De).ips
new file mode 100644
index 00000000..6dfcdebf
--- /dev/null
+++ b/patches/b9d6269d-Joe & Mac 3 - Lost in the Tropics (Europe) (En,Fr,De).ips
Binary files differ
diff --git a/patches/bbcd16f4-Soccer Shootout (Europe).ips b/patches/bbcd16f4-Soccer Shootout (Europe).ips
new file mode 100644
index 00000000..3611acc6
--- /dev/null
+++ b/patches/bbcd16f4-Soccer Shootout (Europe).ips
Binary files differ
diff --git a/patches/d190cf58-Eric Cantona Football Challenge (France) (En,Fr,De,Es,It,Nl,Sv).ips b/patches/d190cf58-Eric Cantona Football Challenge (France) (En,Fr,De,Es,It,Nl,Sv).ips
new file mode 100644
index 00000000..82776020
--- /dev/null
+++ b/patches/d190cf58-Eric Cantona Football Challenge (France) (En,Fr,De,Es,It,Nl,Sv).ips
Binary files differ
diff --git a/patches/d56c21a1-Donald in Maui Mallard (Europe).ips b/patches/d56c21a1-Donald in Maui Mallard (Europe).ips
new file mode 100644
index 00000000..f6cfa1ce
--- /dev/null
+++ b/patches/d56c21a1-Donald in Maui Mallard (Europe).ips
Binary files differ
diff --git a/patches/e4925f15-Adventures of Dr. Franken, The (Europe) (En,Fr,De,Es,It,Nl,Sv).ips b/patches/e4925f15-Adventures of Dr. Franken, The (Europe) (En,Fr,De,Es,It,Nl,Sv).ips
new file mode 100644
index 00000000..afef7303
--- /dev/null
+++ b/patches/e4925f15-Adventures of Dr. Franken, The (Europe) (En,Fr,De,Es,It,Nl,Sv).ips
Binary files differ
diff --git a/patches/f1dce2b7-Tintin in Tibet (Europe) (En,Fr,De,Nl).ips b/patches/f1dce2b7-Tintin in Tibet (Europe) (En,Fr,De,Nl).ips
new file mode 100644
index 00000000..f719e2bf
--- /dev/null
+++ b/patches/f1dce2b7-Tintin in Tibet (Europe) (En,Fr,De,Nl).ips
Binary files differ
diff --git a/patches/fabff8bd-Zombies (Europe).ips b/patches/fabff8bd-Zombies (Europe).ips
new file mode 100644
index 00000000..1b1341d8
--- /dev/null
+++ b/patches/fabff8bd-Zombies (Europe).ips
Binary files differ
diff --git a/patches/fb1d16c4-Super Ice Hockey (Europe).ips b/patches/fb1d16c4-Super Ice Hockey (Europe).ips
new file mode 100644
index 00000000..9c13efb3
--- /dev/null
+++ b/patches/fb1d16c4-Super Ice Hockey (Europe).ips
Binary files differ
diff --git a/patches/fce7bade-Kevin Keegan's Player Manager (Europe).ips b/patches/fce7bade-Kevin Keegan's Player Manager (Europe).ips
new file mode 100644
index 00000000..3f2fda55
--- /dev/null
+++ b/patches/fce7bade-Kevin Keegan's Player Manager (Europe).ips
Binary files differ
diff --git a/user_mods/snes_custom_filters.hmod/canoe-custom-filters b/user_mods/snes_custom_filters.hmod/canoe-custom-filters
new file mode 100644
index 00000000..236088a9
--- /dev/null
+++ b/user_mods/snes_custom_filters.hmod/canoe-custom-filters
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+set -x
+
+export MALI_NOCLEAR=1
+
+decorative_options()
+{
+ local fn="$1_options.txt"
+ if [ ! -f "$fn" ] ; then
+ return
+ fi
+ while read option ; do
+ case "$option" in
+ hue) printf ' --decorative-frame-hue';;
+ luminosity) printf ' --decorative-frame-luminosity';;
+ saturation) printf ' --decorative-frame-saturation';;
+ esac
+ done < "$fn"
+}
+
+original_options=$@
+options=""
+clovercon_file=/dev/clovercon1
+video_mode=keep-aspect-ratio
+mode1="-filter 2 -magfilter 1"
+mode2="-filter 1 -magfilter 3"
+mode3="-filter 1 --pixel-perfect"
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --title-code) title_code="$2"; shift ;;
+ --load-state-file) options="$options -resume" ;;
+ --save-data-backing-file) options="$options --sram-file" ;;
+ --replay-inputs) options="$options -replay-all -replay" ;;
+ --record-inputs) options="$options -record-next -enable-pad-debug-controls" ;;
+ --video-mode)
+ video_mode=$2
+ shift
+ ;;
+ --no-scanlines)
+ mode1="-filter 1 -magfilter 1"
+ ;;
+ --no-smooth)
+ mode1="-filter 2 -magfilter 3"
+ ;;
+ --smooth43)
+ mode2="-filter 1 -magfilter 1"
+ ;;
+ --rollback-mode)
+ case "$2" in
+ record) options="$options -rollback-mode 1" ;;
+ replay) options="$options -rollback-mode 2" ;;
+ esac
+ options="$options --rollback-ui /usr/share/canoe/rollback-ui"
+ options="-rollback-snapshot-period 720 $options"
+ options="$options --enable-sram-file-hash"
+ shift
+ ;;
+ --rollback-output-dir) options="$options -rollback-output-dir $2"; shift ;;
+ --rollback-input-dir) options="$options -rollback-input-dir $2"; shift ;;
+ --decorative-frame-path) options="$options --use-decorative-frame $2 $(decorative_options $2)"; shift ;;
+ *.sfrom)
+ if [ -f "$1.gz" ]; then
+ options="$options /tmp/ROM.sfrom"
+ gunzip -c "$1.gz" > /tmp/ROM.sfrom
+ rom=/tmp/ROM.sfrom
+ else
+ options="$options $1"
+ rom=$1
+ fi
+ ;;
+ *) options="$options $1" ;;
+ esac
+ shift
+done
+
+case "$video_mode" in
+ keep-aspect-ratio) options="$options $mode2" ;;
+ pixel-perfect) options="$options $mode3" ;;
+ crt-filter) options="$options $mode1" ;;
+esac
+
+read BUILD_TYPE < /etc/clover/buildtype
+case "$BUILD_TYPE" in
+devel) log="-log $title_code.log -log-append --debug-menu-settings /var/lib/clover/canoe/debug-menu.json --decorative-frames-path /usr/share/backgrounds" ;;
+test) log="-log $title_code.log" ;;
+*) ;;
+esac
+
+exec canoe-shvc $options $log
diff --git a/user_mods/snes_custom_filters.hmod/install b/user_mods/snes_custom_filters.hmod/install
new file mode 100644
index 00000000..d079aca1
--- /dev/null
+++ b/user_mods/snes_custom_filters.hmod/install
@@ -0,0 +1,5 @@
+copy "$transferpath/p8030_snes_filters" "$preinitpath"
+mkdir -p "$rootfs/usr/bin"
+chmod +x "$transferpath/canoe-custom-filters"
+copy "$transferpath/canoe-custom-filters" "$rootfs/usr/bin/"
+return 1
diff --git a/user_mods/snes_custom_filters.hmod/p8030_snes_filters b/user_mods/snes_custom_filters.hmod/p8030_snes_filters
new file mode 100644
index 00000000..a2025094
--- /dev/null
+++ b/user_mods/snes_custom_filters.hmod/p8030_snes_filters
@@ -0,0 +1 @@
+[ -f "$mountpoint/usr/bin/clover-canoe-shvc" ] && overmount /usr/bin/canoe-custom-filters /usr/bin/clover-canoe-shvc
diff --git a/user_mods/snes_custom_filters.hmod/readme.txt b/user_mods/snes_custom_filters.hmod/readme.txt
new file mode 100644
index 00000000..60da611c
--- /dev/null
+++ b/user_mods/snes_custom_filters.hmod/readme.txt
@@ -0,0 +1,14 @@
+=== No-thumbnails Hack ===
+
+This module allows to tweak video filters on SNES Mini or Super Famicom Mini (yes, only SNES, not NES/Famicom).
+
+You need to add special command line arguments to make it work. Just add those arguments to game's command line or to global command line arguments.
+
+Argument to enable bilinear filter in 4:3 mode:
+ --smooth43
+
+Argument to disable scanlines in CRT mode (bilinear filter only):
+ --no-scanlines
+
+Argument to disable bilinear filter in CRT mode (scanlines only):
+ --no-smooth
diff --git a/user_mods/snes_custom_filters.hmod/uninstall b/user_mods/snes_custom_filters.hmod/uninstall
new file mode 100644
index 00000000..f5e8568e
--- /dev/null
+++ b/user_mods/snes_custom_filters.hmod/uninstall
@@ -0,0 +1,2 @@
+rm "$preinitpath/p8030_snes_filters"
+rm "$rootfs/usr/bin/p8030_snes_filters"