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
path: root/Apps
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2017-10-05 07:05:16 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2017-10-05 07:05:16 +0300
commit01c8b9149f139648ed53fe175bbc955443c2ef01 (patch)
tree5e9ae2af9d2cf2602bbf4ca40ee2348f4af06d2a /Apps
parente0b2f51d15924c3353393072be25f8bb3d3e45d2 (diff)
Huge refactoring. Testing required. But need to sleep.
Diffstat (limited to 'Apps')
-rw-r--r--Apps/AppTypeCollection.cs36
-rw-r--r--Apps/FdsGame.cs47
-rw-r--r--Apps/ICloverAutofill.cs13
-rw-r--r--Apps/INesMenuElement.cs9
-rw-r--r--Apps/ISupportsGameGenie.cs14
-rw-r--r--Apps/NesGame.cs130
-rw-r--r--Apps/NesMiniApplication.cs310
-rw-r--r--Apps/SnesGame.cs9
8 files changed, 361 insertions, 207 deletions
diff --git a/Apps/AppTypeCollection.cs b/Apps/AppTypeCollection.cs
index 79061fa3..a43ee78e 100644
--- a/Apps/AppTypeCollection.cs
+++ b/Apps/AppTypeCollection.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
namespace com.clusterrr.hakchi_gui
{
@@ -24,25 +25,33 @@ namespace com.clusterrr.hakchi_gui
{
new AppInfo
{
- Class = typeof(FdsGame),
- Extensions = new string[] {".fds"},
- DefaultApps = new string[] {},
- Prefix = 'D',
- DefaultCover = Resources.blank_fds
+ Class = typeof(NesGame),
+ Extensions = new string[] {".nes"},
+ DefaultApps = new string[] {"/bin/clover-kachikachi-wr", "/bin/clover-kachikachi", "/bin/nes"},
+ Prefix = 'H',
+ DefaultCover = Resources.blank_nes
},
new AppInfo
{
Class = typeof(NesUGame),
- Extensions = new string[] {".nes", ".unf", ".unif"},
+ Extensions = new string[] {".unf", ".unif", ".nes", ".fds" },
DefaultApps = new string[] {"/bin/nes"},
Prefix = 'I',
DefaultCover = Resources.blank_jp
},
new AppInfo
{
+ Class = typeof(FdsGame),
+ Extensions = new string[] {".fds"},
+ DefaultApps = new string[] {"/bin/clover-kachikachi-wr", "/bin/clover-kachikachi", "/bin/nes"},
+ Prefix = 'D',
+ DefaultCover = Resources.blank_fds
+ },
+ new AppInfo
+ {
Class = typeof(SnesGame),
- Extensions = new string[] { ".sfc", ".smc" },
- DefaultApps = new string[] {"/bin/snes"},
+ Extensions = new string[] { ".sfc", ".smc", ".sfrom" },
+ DefaultApps = new string[] {"/usr/bin/clover-canoe-shvc", "/bin/snes"},
Prefix = 'U',
DefaultCover = Resources.blank_snes_us
},
@@ -146,10 +155,19 @@ namespace com.clusterrr.hakchi_gui
public static AppInfo GetAppByExec(string exec)
{
+ exec = Regex.Replace(exec, "['\\\"]|(\\.7z)", " ")+" ";
foreach (var app in ApplicationTypes)
foreach (var cmd in app.DefaultApps)
if (exec.StartsWith(cmd + " "))
- return app;
+ {
+ if (app.Extensions.Length == 0)
+ return app;
+ foreach (var ext in app.Extensions)
+ {
+ if (exec.Contains(ext + " "))
+ return app;
+ }
+ }
return null;
}
}
diff --git a/Apps/FdsGame.cs b/Apps/FdsGame.cs
index acb656c1..f5072215 100644
--- a/Apps/FdsGame.cs
+++ b/Apps/FdsGame.cs
@@ -11,62 +11,35 @@ namespace com.clusterrr.hakchi_gui
public class FdsGame : NesMiniApplication
{
const string DefaultArgs = "--guest-overscan-dimensions 0,0,9,3 --initial-fadein-durations 10,2 --volume 75 --enable-armet --fds-auto-disk-side-switch-on-keypress";
+ const char Prefix = 'D';
public override string GoogleSuffix
{
get
{
- return "fds";
+ return "(fds | nes | famicom)";
}
}
- public string Args
- {
- get
- {
- if (Command.Contains(".fds"))
- return Command.Substring(Command.IndexOf(".fds") + 4).Trim();
- else
- return "";
- }
- set
- {
- Command = string.Format("/bin/clover-kachikachi-wr /usr/share/games/nes/kachikachi/{0}/{0}.fds {1}", code, value);
- }
- }
-
public FdsGame(string path, bool ignoreEmptyConfig = false)
: base(path, ignoreEmptyConfig)
{
- Args = Args; // To update exec path if need
}
- public static FdsGame Import(string fdsFileName, string sourceFileName, byte[] rawRomData = null)
+ public static bool Patch(string inputFileName, ref byte[] rawRomData, ref char prefix, ref string application, ref string outputFileName, ref string args, ref Image cover, ref uint crc32)
{
- if (rawRomData == null)
- rawRomData = File.ReadAllBytes(fdsFileName);
+ FindPatch(ref rawRomData, inputFileName, crc32);
if (Encoding.ASCII.GetString(rawRomData, 0, 3) == "FDS") // header? cut it!
{
var fdsDataNoHeader = new byte[rawRomData.Length - 0x10];
Array.Copy(rawRomData, 0x10, fdsDataNoHeader, 0, fdsDataNoHeader.Length);
rawRomData = fdsDataNoHeader;
- }
- var crc32 = CRC32(rawRomData);
- var code = GenerateCode(crc32, DefaultPrefix);
- var gamePath = Path.Combine(GamesDirectory, code);
- var fdsPath = Path.Combine(gamePath, code + ".fds");
- Directory.CreateDirectory(gamePath);
- File.WriteAllBytes(fdsPath, rawRomData);
- var game = new FdsGame(gamePath, true);
-
- game.Name = Path.GetFileNameWithoutExtension(fdsFileName);
- game.Name = Regex.Replace(game.Name, @" ?\(.*?\)", string.Empty).Trim();
- game.Name = Regex.Replace(game.Name, @" ?\[.*?\]", string.Empty).Trim();
- game.Name = game.Name.Replace("_", " ").Replace(" ", " ").Trim();
- game.FindCover(fdsFileName, sourceFileName, Resources.blank_fds, crc32);
- game.Args = DefaultArgs;
- game.Save();
- return game;
+ crc32 = CRC32(rawRomData);
+ // Try to find patch again, using new CRC
+ FindPatch(ref rawRomData, inputFileName, crc32);
+ }
+ args = DefaultArgs;
+ return true;
}
}
}
diff --git a/Apps/ICloverAutofill.cs b/Apps/ICloverAutofill.cs
new file mode 100644
index 00000000..50fb88c8
--- /dev/null
+++ b/Apps/ICloverAutofill.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+
+namespace com.clusterrr.hakchi_gui
+{
+ interface ICloverAutofill
+ {
+ bool TryAutofill(uint crc32);
+ }
+}
diff --git a/Apps/INesMenuElement.cs b/Apps/INesMenuElement.cs
new file mode 100644
index 00000000..18ece9a5
--- /dev/null
+++ b/Apps/INesMenuElement.cs
@@ -0,0 +1,9 @@
+
+namespace com.clusterrr.hakchi_gui
+{
+ public interface INesMenuElement
+ {
+ string Code { get; }
+ string Name { get; set; }
+ }
+}
diff --git a/Apps/ISupportsGameGenie.cs b/Apps/ISupportsGameGenie.cs
new file mode 100644
index 00000000..580572da
--- /dev/null
+++ b/Apps/ISupportsGameGenie.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace com.clusterrr.hakchi_gui
+{
+ interface ISupportsGameGenie
+ {
+ string GameGeniePath { get; }
+ string GameGenie { get; set; }
+ void ApplyGameGenie();
+ }
+}
diff --git a/Apps/NesGame.cs b/Apps/NesGame.cs
index 35a814d5..66dc86a7 100644
--- a/Apps/NesGame.cs
+++ b/Apps/NesGame.cs
@@ -4,6 +4,7 @@ using com.clusterrr.hakchi_gui.Properties;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Drawing;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
@@ -12,15 +13,16 @@ using System.Xml.XPath;
namespace com.clusterrr.hakchi_gui
{
- public class NesGame : NesMiniApplication
+ public class NesGame : NesMiniApplication, ICloverAutofill, ISupportsGameGenie
{
- public delegate bool NeedPatchDelegate(Form parentForm, string nesFileName);
public const char Prefix = 'H';
- public readonly string NesPath;
- public readonly string GameGeniePath;
-
- private string region = null;
+ public string GameGeniePath { private set; get; }
+ public static bool? IgnoreMapper;
const string DefaultArgs = "--guest-overscan-dimensions 0,0,9,3 --initial-fadein-durations 10,2 --volume 75 --enable-armet";
+ private static Dictionary<uint, CachedGameInfo> gameInfoCache = null;
+
+ public const string GameGenieFileName = "gamegenie.txt";
+ private static byte[] supportedMappers = new byte[] { 0, 1, 2, 3, 4, 5, 7, 9, 10, 86, 87, 184 };
public override string GoogleSuffix
{
@@ -30,20 +32,6 @@ namespace com.clusterrr.hakchi_gui
}
}
- public string Args
- {
- get
- {
- if (Command.Contains(".nes"))
- return Command.Substring(Command.IndexOf(".nes") + 4).Trim();
- else
- return "";
- }
- set
- {
- Command = string.Format("/bin/clover-kachikachi-wr /usr/share/games/nes/kachikachi/{0}/{0}.nes {1}", code, value);
- }
- }
private string gameGenie = "";
public string GameGenie
{
@@ -54,28 +42,76 @@ namespace com.clusterrr.hakchi_gui
gameGenie = value;
}
}
- public string Region
- {
- get { return region; }
- private set { region = value; }
- }
-
- private static Dictionary<uint, CachedGameInfo> gameInfoCache = null;
- public const string GameGenieFileName = "gamegenie.txt";
- private static byte[] supportedMappers = new byte[] { 0, 1, 2, 3, 4, 5, 7, 9, 10, 86, 87, 184 };
public NesGame(string path, bool ignoreEmptyConfig = false)
: base(path, ignoreEmptyConfig)
{
- NesPath = Path.Combine(GamePath, Code + ".nes");
- GameGeniePath = Path.Combine(path, GameGenieFileName);
- if (!File.Exists(NesPath)) throw new FileNotFoundException("Invalid game directory: " + path);
-
+ GameGeniePath = System.IO.Path.Combine(path, GameGenieFileName);
if (File.Exists(GameGeniePath))
gameGenie = File.ReadAllText(GameGeniePath);
- Args = Args; // To update exec path if need
}
+
+ public static bool Patch(string inputFileName, ref byte[] rawRomData, ref char prefix, ref string application, ref string outputFileName, ref string args, ref Image cover, ref uint crc32)
+ {
+ // Try to patch before mapper check, maybe it will patch mapper
+ FindPatch(ref rawRomData, inputFileName, crc32);
+ NesFile nesFile;
+ try
+ {
+ nesFile = new NesFile(rawRomData);
+ }
+ catch
+ {
+ application = "/bin/nes";
+ return true;
+ }
+ nesFile.CorrectRom();
+ crc32 = nesFile.CRC32;
+ if (ConfigIni.ConsoleType != MainForm.ConsoleType.NES && ConfigIni.ConsoleType != MainForm.ConsoleType.Famicom)
+ application = "/bin/nes";
+
+ //if (nesFile.Mapper == 71) nesFile.Mapper = 2; // games by Codemasters/Camerica - this is UNROM clone. One exception - Fire Hawk
+ //if (nesFile.Mapper == 88) nesFile.Mapper = 4; // Compatible with MMC3... sometimes
+ //if (nesFile.Mapper == 95) nesFile.Mapper = 4; // Compatible with MMC3
+ //if (nesFile.Mapper == 206) nesFile.Mapper = 4; // Compatible with MMC3
+ if (!supportedMappers.Contains(nesFile.Mapper) && (IgnoreMapper != true))
+ {
+ if (IgnoreMapper != false)
+ {
+ var r = WorkerForm.MessageBoxFromThread(ParentForm,
+ string.Format(Resources.MapperNotSupported, System.IO.Path.GetFileName(inputFileName), nesFile.Mapper),
+ Resources.AreYouSure,
+ MessageBoxButtons.AbortRetryIgnore,
+ MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, true);
+ if (r == DialogResult.Abort)
+ IgnoreMapper = true;
+ if (r == DialogResult.Ignore)
+ return false;
+ }
+ else return false;
+ }
+ if ((nesFile.Mirroring == NesFile.MirroringType.FourScreenVram) && (IgnoreMapper != true))
+ {
+ var r = WorkerForm.MessageBoxFromThread(ParentForm,
+ string.Format(Resources.FourScreenNotSupported, System.IO.Path.GetFileName(inputFileName)),
+ Resources.AreYouSure,
+ MessageBoxButtons.AbortRetryIgnore,
+ MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, true);
+ if (r == DialogResult.Abort)
+ IgnoreMapper = true;
+ if (r == DialogResult.No)
+ return false;
+ }
+
+ // TODO: Make trainer check. I think that the NES Mini doesn't support it.
+ rawRomData = nesFile.GetRaw();
+ if (inputFileName.Contains("(J)")) cover = Resources.blank_jp;
+ args = DefaultArgs;
+ return true;
+ }
+
+ /*
public static NesMiniApplication Import(string nesFileName, string sourceFileName, bool? ignoreMapper, ref bool? needPatch, NeedPatchDelegate needPatchCallback = null, Form parentForm = null, byte[] rawRomData = null)
{
NesFile nesFile;
@@ -114,10 +150,6 @@ namespace com.clusterrr.hakchi_gui
else needPatch = false;
}
- //if (nesFile.Mapper == 71) nesFile.Mapper = 2; // games by Codemasters/Camerica - this is UNROM clone. One exception - Fire Hawk
- //if (nesFile.Mapper == 88) nesFile.Mapper = 4; // Compatible with MMC3... sometimes
- //if (nesFile.Mapper == 95) nesFile.Mapper = 4; // Compatible with MMC3
- //if (nesFile.Mapper == 206) nesFile.Mapper = 4; // Compatible with MMC3
if (!supportedMappers.Contains(nesFile.Mapper) && (ignoreMapper != true))
{
Directory.Delete(gamePath, true);
@@ -156,6 +188,7 @@ namespace com.clusterrr.hakchi_gui
game.Save();
return game;
}
+ */
public bool TryAutofill(uint crc32)
{
@@ -170,7 +203,6 @@ namespace com.clusterrr.hakchi_gui
if (ReleaseDate.Length == 4) ReleaseDate += "-01";
if (ReleaseDate.Length == 7) ReleaseDate += "-01";
Publisher = gameinfo.Publisher.ToUpper();
- Region = gameinfo.Region;
return true;
}
return false;
@@ -178,14 +210,15 @@ namespace com.clusterrr.hakchi_gui
public override bool Save()
{
- if (this.hasUnsavedChanges)
+ var old = hasUnsavedChanges;
+ if (hasUnsavedChanges)
{
if (!string.IsNullOrEmpty(gameGenie))
File.WriteAllText(GameGeniePath, gameGenie);
else
File.Delete(GameGeniePath);
}
- return base.Save() || this.hasUnsavedChanges;
+ return base.Save() || old;
}
public void ApplyGameGenie()
@@ -193,12 +226,16 @@ namespace com.clusterrr.hakchi_gui
if (!string.IsNullOrEmpty(GameGenie))
{
var codes = GameGenie.Split(new char[] { ',', '\t', ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
- var nesFile = new NesFile(NesPath);
- foreach (var code in codes)
+ var nesFiles = Directory.GetFiles(this.Path, "*.nes", SearchOption.TopDirectoryOnly);
+ foreach (var f in nesFiles)
{
- nesFile.PRG = GameGeniePatcher.Patch(nesFile.PRG, code.Trim());
+ var nesFile = new NesFile(f);
+ foreach (var code in codes)
+ {
+ nesFile.PRG = GameGeniePatcher.Patch(nesFile.PRG, code.Trim());
+ }
+ nesFile.Save(f);
}
- nesFile.Save(NesPath);
}
}
@@ -215,7 +252,7 @@ namespace com.clusterrr.hakchi_gui
{
try
{
- var xmlDataBasePath = Path.Combine(Path.Combine(Program.BaseDirectoryInternal, "data"), "nescarts.xml");
+ var xmlDataBasePath = System.IO.Path.Combine(System.IO.Path.Combine(Program.BaseDirectoryInternal, "data"), "nescarts.xml");
Debug.WriteLine("Loading " + xmlDataBasePath);
if (File.Exists(xmlDataBasePath))
@@ -254,6 +291,7 @@ namespace com.clusterrr.hakchi_gui
Debug.WriteLine(ex.Message + ex.StackTrace);
}
}
+
}
}
diff --git a/Apps/NesMiniApplication.cs b/Apps/NesMiniApplication.cs
index 3b0ab9bf..437253ce 100644
--- a/Apps/NesMiniApplication.cs
+++ b/Apps/NesMiniApplication.cs
@@ -14,6 +14,14 @@ namespace com.clusterrr.hakchi_gui
{
public class NesMiniApplication : INesMenuElement
{
+ internal const string DefaultApp = "/bin/path-to-your-app";
+ const string DefaultReleaseDate = "1900-01-01";
+ const string DefaultPublisher = "UNKNOWN";
+ public const char DefaultPrefix = 'Z';
+ public static Image DefaultCover = Resources.blank_app;
+ public static Form ParentForm;
+ public static bool? NeedPatch;
+
public static string GamesDirectory
{
get
@@ -23,10 +31,10 @@ namespace com.clusterrr.hakchi_gui
default:
case MainForm.ConsoleType.NES:
case MainForm.ConsoleType.Famicom:
- return Path.Combine(Program.BaseDirectoryExternal, "games");
+ return System.IO.Path.Combine(Program.BaseDirectoryExternal, "games");
case MainForm.ConsoleType.SNES:
case MainForm.ConsoleType.SuperFamicom:
- return Path.Combine(Program.BaseDirectoryExternal, "games_snes");
+ return System.IO.Path.Combine(Program.BaseDirectoryExternal, "games_snes");
}
}
}
@@ -47,23 +55,17 @@ namespace com.clusterrr.hakchi_gui
}
}
- const string DefaultReleaseDate = "1900-01-01";
- const string DefaultPublisher = "UNKNOWN";
-
protected string code;
public string Code
{
get { return code; }
}
- public const char DefaultPrefix = 'Z';
- public static Image DefaultCover { get { return Resources.blank_app; } }
- internal const string DefaultApp = "/bin/path-to-your-app";
public virtual string GoogleSuffix
{
get { return "game"; }
}
- public readonly string GamePath;
+ public readonly string Path;
public readonly string ConfigPath;
public readonly string IconPath;
public readonly string SmallIconPath;
@@ -141,13 +143,6 @@ namespace com.clusterrr.hakchi_gui
if (line.StartsWith("Exec="))
{
string command = line.Substring(5);
- if (command.StartsWith("/usr/bin/clover-kachikachi") || command.StartsWith("/bin/clover-kachikachi-wr"))
- {
- if (command.Contains(".nes"))
- return new NesGame(path, ignoreEmptyConfig);
- if (command.Contains(".fds"))
- return new FdsGame(path, ignoreEmptyConfig);
- }
var app = AppTypeCollection.GetAppByExec(command);
if (app != null)
{
@@ -160,92 +155,92 @@ namespace com.clusterrr.hakchi_gui
return new NesMiniApplication(path, ignoreEmptyConfig);
}
- public static NesMiniApplication Import(string fileName, string sourceFile = null, byte[] rawRomData = null)
+ public static NesMiniApplication Import(string inputFileName, string originalFileName = null, byte[] rawRomData = null)
{
- var extension = Path.GetExtension(fileName).ToLower();
+ var extension = System.IO.Path.GetExtension(inputFileName).ToLower();
if (extension == ".desktop")
- return ImportApp(fileName);
- if (rawRomData == null)
- rawRomData = File.ReadAllBytes(fileName);
- var appinfo = AppTypeCollection.GetAppByExtension(extension);
- if (appinfo != null)
- {
- var import = appinfo.Class.GetMethod("Import", new Type[] { typeof(string), typeof(string), typeof(byte[]) });
- if (import != null)
- return (NesMiniApplication)import.Invoke(null, new object[] { fileName, sourceFile, rawRomData });
- else
- return Import(fileName, sourceFile, rawRomData, appinfo.Prefix,
- appinfo.DefaultApps.Length > 0 ? appinfo.DefaultApps[0] : DefaultApp,
- appinfo.DefaultCover, ConfigIni.Compress);
- }
+ return ImportApp(inputFileName);
+ if (rawRomData == null) // Maybe it's already extracted data?
+ rawRomData = File.ReadAllBytes(inputFileName); // If not, reading file
+ if (originalFileName == null) // Original file name from archive
+ originalFileName = System.IO.Path.GetFileName(inputFileName);
+ char prefix = DefaultPrefix;
string application = extension.Length > 2 ? ("/bin/" + extension.Substring(1)) : DefaultApp;
- return Import(fileName, sourceFile, rawRomData, DefaultPrefix, application, DefaultCover);
- }
+ string args = null;
+ Image cover = DefaultCover;
+ uint crc32 = CRC32(rawRomData);
+ string outputFileName = Regex.Replace(System.IO.Path.GetFileName(inputFileName), @"[^A-Za-z0-9()!\[\]\.\-]", "_").Trim();
- private static NesMiniApplication Import(string fileName, string sourceFile, byte[] rawRomData, char prefixCode, string application, Image defaultCover, bool compress = false)
- {
- var crc32 = CRC32(rawRomData);
- var code = GenerateCode(crc32, prefixCode);
- var gamePath = Path.Combine(GamesDirectory, code);
- bool sevenZipped = false;
- if (compress)
+ // Trying to determine file type
+ var appinfo = AppTypeCollection.GetAppByExtension(extension);
+ bool patched = false;
+ if (appinfo != null)
{
- string temp = null;
- try
- {
- if (!File.Exists(fileName))
- {
- temp = Path.Combine(Path.GetTempPath(), Path.GetFileName(fileName));
- File.WriteAllBytes(temp, rawRomData);
- rawRomData = Compress(temp);
- sevenZipped = true;
- }
- else
- {
- rawRomData = Compress(fileName);
- sevenZipped = true;
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Compression error: " + ex.Message + ex.Source);
- }
- finally
+ if (appinfo.DefaultApps.Length > 0)
+ application = appinfo.DefaultApps[0];
+ prefix = appinfo.Prefix;
+ cover = appinfo.DefaultCover;
+ var patch = appinfo.Class.GetMethod("Patch");
+ if (patch != null)
{
- if (!string.IsNullOrEmpty(temp) && File.Exists(temp))
- File.Delete(temp);
+ object[] values = new object[] { inputFileName, rawRomData, prefix, application, outputFileName, args, cover, crc32 };
+ var result = (bool)patch.Invoke(null, values);
+ if (!result) return null;
+ rawRomData = (byte[])values[1];
+ prefix = (char)values[2];
+ application = (string)values[3];
+ outputFileName = (string)values[4];
+ args = (string)values[5];
+ cover = (Image)values[6];
+ crc32 = (uint)values[7];
+ patched = true;
}
}
- var romName = Regex.Replace(Path.GetFileName(fileName), @"[^A-Za-z0-9.-]", "_").Trim() + (sevenZipped ? ".7z" : "");
- var romPath = Path.Combine(gamePath, romName);
+
+ if (!patched)
+ FindPatch(ref rawRomData, inputFileName, crc32);
+
+ var code = GenerateCode(crc32, prefix);
+ var gamePath = System.IO.Path.Combine(GamesDirectory, code);
+ var romPath = System.IO.Path.Combine(gamePath, outputFileName);
if (Directory.Exists(gamePath))
Directory.Delete(gamePath, true);
Directory.CreateDirectory(gamePath);
File.WriteAllBytes(romPath, rawRomData);
var game = new NesMiniApplication(gamePath, true);
- game.Name = Path.GetFileNameWithoutExtension(fileName);
+ game.Name = System.IO.Path.GetFileNameWithoutExtension(inputFileName);
game.Name = Regex.Replace(game.Name, @" ?\(.*?\)", string.Empty).Trim();
game.Name = Regex.Replace(game.Name, @" ?\[.*?\]", string.Empty).Trim();
game.Name = game.Name.Replace("_", " ").Replace(" ", " ").Trim();
- game.FindCover(fileName, sourceFile, defaultCover, crc32);
- game.Command = string.Format("{0} /usr/share/games/nes/kachikachi/{1}/{2}", application, code, romName);
+ game.Command = $"{application} {GamesCloverPath}/{code}/{outputFileName}";
+ if (!string.IsNullOrEmpty(args))
+ game.Command += " " + args;
+ game.FindCover(inputFileName, cover, crc32);
game.Save();
- return NesMiniApplication.FromDirectory(gamePath);
+
+ var app = NesMiniApplication.FromDirectory(gamePath);
+ if (app is ICloverAutofill)
+ (app as ICloverAutofill).TryAutofill(crc32);
+
+ if (ConfigIni.Compress)
+ app.Compress();
+
+ return app;
}
private static NesMiniApplication ImportApp(string fileName)
{
if (!File.Exists(fileName)) // Archives are not allowed
throw new FileNotFoundException("Invalid app folder");
- var code = Path.GetFileNameWithoutExtension(fileName).ToUpper();
- var targetDir = Path.Combine(GamesDirectory, code);
- DirectoryCopy(Path.GetDirectoryName(fileName), targetDir, true);
+ var code = System.IO.Path.GetFileNameWithoutExtension(fileName).ToUpper();
+ var targetDir = System.IO.Path.Combine(GamesDirectory, code);
+ DirectoryCopy(System.IO.Path.GetDirectoryName(fileName), targetDir, true);
return FromDirectory(targetDir);
}
protected NesMiniApplication()
{
- GamePath = null;
+ Path = null;
ConfigPath = null;
Players = 1;
Simultaneous = false;
@@ -256,12 +251,12 @@ namespace com.clusterrr.hakchi_gui
protected NesMiniApplication(string path, bool ignoreEmptyConfig = false)
{
- GamePath = path;
- code = Path.GetFileName(path);
+ Path = path;
+ code = System.IO.Path.GetFileName(path);
Name = Code;
- ConfigPath = Path.Combine(path, Code + ".desktop");
- IconPath = Path.Combine(path, Code + ".png");
- SmallIconPath = Path.Combine(path, Code + "_small.png");
+ ConfigPath = System.IO.Path.Combine(path, Code + ".desktop");
+ IconPath = System.IO.Path.Combine(path, Code + ".png");
+ SmallIconPath = System.IO.Path.Combine(path, Code + "_small.png");
Players = 1;
Simultaneous = false;
ReleaseDate = DefaultReleaseDate;
@@ -390,41 +385,32 @@ namespace com.clusterrr.hakchi_gui
outImageSmall.Save(SmallIconPath, ImageFormat.Png);
}
- internal bool FindCover(string romFileName, string sourceFileName, Image defaultCover, uint crc32 = 0)
+ protected bool FindCover(string inputFileName, Image defaultCover, uint crc32 = 0)
{
// Trying to find cover file
Image cover = null;
- if (!string.IsNullOrEmpty(romFileName))
+ var artDirectory = System.IO.Path.Combine(Program.BaseDirectoryExternal, "art");
+ Directory.CreateDirectory(artDirectory);
+ if (!string.IsNullOrEmpty(inputFileName))
{
- if (!string.IsNullOrEmpty(sourceFileName) && sourceFileName != romFileName)
+ if (crc32 != 0)
{
- var archImagePath = Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileNameWithoutExtension(romFileName) + ".png");
- if (File.Exists(archImagePath))
- cover = LoadBitmap(archImagePath);
- archImagePath = Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileNameWithoutExtension(romFileName) + ".jpg");
- if (File.Exists(archImagePath))
- cover = LoadBitmap(archImagePath);
+ var covers = Directory.GetFiles(artDirectory, string.Format("{0:X8}*.*", crc32), SearchOption.AllDirectories);
+ if (covers.Length > 0)
+ cover = LoadBitmap(covers[0]);
}
- var imagePath = Path.Combine(Path.GetDirectoryName(romFileName), Path.GetFileNameWithoutExtension(romFileName) + ".png");
+ var imagePath = System.IO.Path.Combine(artDirectory, System.IO.Path.GetFileNameWithoutExtension(inputFileName) + ".png");
if (File.Exists(imagePath))
cover = LoadBitmap(imagePath);
- imagePath = Path.Combine(Path.GetDirectoryName(romFileName), Path.GetFileNameWithoutExtension(romFileName) + ".jpg");
+ imagePath = System.IO.Path.Combine(artDirectory, System.IO.Path.GetFileNameWithoutExtension(inputFileName) + ".jpg");
if (File.Exists(imagePath))
cover = LoadBitmap(imagePath);
- var artDirectory = Path.Combine(Program.BaseDirectoryExternal, "art");
- Directory.CreateDirectory(artDirectory);
- imagePath = Path.Combine(artDirectory, Path.GetFileNameWithoutExtension(romFileName) + ".png");
+ imagePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(inputFileName), System.IO.Path.GetFileNameWithoutExtension(inputFileName) + ".png");
if (File.Exists(imagePath))
cover = LoadBitmap(imagePath);
- imagePath = Path.Combine(artDirectory, Path.GetFileNameWithoutExtension(romFileName) + ".jpg");
+ imagePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(inputFileName), System.IO.Path.GetFileNameWithoutExtension(inputFileName) + ".jpg");
if (File.Exists(imagePath))
cover = LoadBitmap(imagePath);
- if (crc32 != 0)
- {
- var covers = Directory.GetFiles(artDirectory, string.Format("{0:X8}*.*", crc32), SearchOption.AllDirectories);
- if (covers.Length > 0)
- cover = LoadBitmap(covers[0]);
- }
}
if (cover == null)
{
@@ -435,6 +421,52 @@ namespace com.clusterrr.hakchi_gui
return true;
}
+ protected static bool FindPatch(ref byte[] rawRomData, string inputFileName, uint crc32 = 0)
+ {
+ string patch = null;
+ var patchesDirectory = System.IO.Path.Combine(Program.BaseDirectoryExternal, "patches");
+ Directory.CreateDirectory(patchesDirectory);
+ if (!string.IsNullOrEmpty(inputFileName))
+ {
+ if (crc32 != 0)
+ {
+ var patches = Directory.GetFiles(patchesDirectory, string.Format("{0:X8}*.*", crc32), SearchOption.AllDirectories);
+ if (patches.Length > 0)
+ patch = patches[0];
+ }
+ var patchesPath = System.IO.Path.Combine(patchesDirectory, System.IO.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");
+ if (File.Exists(patchesPath))
+ patch = patchesPath;
+ }
+
+ if (!string.IsNullOrEmpty(patch))
+ {
+ if (NeedPatch != true)
+ {
+ if (NeedPatch != false)
+ {
+ var r = WorkerForm.MessageBoxFromThread(ParentForm,
+ string.Format(Resources.PatchQ, System.IO.Path.GetFileName(inputFileName)),
+ Resources.PatchAvailable,
+ MessageBoxButtons.AbortRetryIgnore,
+ MessageBoxIcon.Question,
+ MessageBoxDefaultButton.Button2, true);
+ if (r == DialogResult.Abort)
+ NeedPatch = true;
+ if (r == DialogResult.Ignore)
+ return false;
+ }
+ else return false;
+ }
+ IpsPatcher.Patch(patch, ref rawRomData);
+ return true;
+ }
+ return false;
+ }
+
protected static string GenerateCode(uint crc32, char prefixCode)
{
return string.Format("CLV-{5}-{0}{1}{2}{3}{4}",
@@ -448,8 +480,8 @@ namespace com.clusterrr.hakchi_gui
public NesMiniApplication CopyTo(string path)
{
- var targetDir = Path.Combine(path, code);
- DirectoryCopy(GamePath, targetDir, true);
+ var targetDir = System.IO.Path.Combine(path, code);
+ DirectoryCopy(Path, targetDir, true);
return FromDirectory(targetDir);
}
@@ -477,7 +509,7 @@ namespace com.clusterrr.hakchi_gui
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
- string temppath = Path.Combine(destDirName, file.Name);
+ string temppath = System.IO.Path.Combine(destDirName, file.Name);
size += file.CopyTo(temppath, true).Length;
}
@@ -486,7 +518,7 @@ namespace com.clusterrr.hakchi_gui
{
foreach (DirectoryInfo subdir in dirs)
{
- string temppath = Path.Combine(destDirName, subdir.Name);
+ string temppath = System.IO.Path.Combine(destDirName, subdir.Name);
size += DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
@@ -496,7 +528,7 @@ namespace com.clusterrr.hakchi_gui
public long Size(string path = null)
{
if (path == null)
- path = GamePath;
+ path = Path;
long size = 0;
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(path);
@@ -565,17 +597,65 @@ namespace com.clusterrr.hakchi_gui
}
}
- private static byte[] Compress(string filename)
+ public string[] CompressPossible()
{
- SevenZipExtractor.SetLibraryPath(Path.Combine(Program.BaseDirectoryInternal, IntPtr.Size == 8 ? @"tools\7z64.dll" : @"tools\7z.dll"));
- var arch = new MemoryStream();
- var compressor = new SevenZipCompressor();
- compressor.CompressionLevel = CompressionLevel.High;
- compressor.CompressFiles(arch, filename);
- arch.Seek(0, SeekOrigin.Begin);
- var result = new byte[arch.Length];
- arch.Read(result, 0, result.Length);
- return result;
+ var result = new List<string>();
+ var exec = Regex.Replace(Command, "['\\\"]", " ") + " ";
+ var files = Directory.GetFiles(Path, "*.*", SearchOption.TopDirectoryOnly);
+ foreach (var file in files)
+ {
+ if (System.IO.Path.GetExtension(file).ToLower() == ".7z")
+ continue;
+ if (System.IO.Path.GetExtension(file).ToLower() == ".zip")
+ continue;
+ if (exec.Contains(System.IO.Path.GetFileName(file) + " "))
+ result.Add(file);
+ }
+ return result.ToArray();
+ }
+
+ public string[] DecompressPossible()
+ {
+ var result = new List<string>();
+ var exec = Regex.Replace(Command, "['\\\"]", " ") + " ";
+ var files = Directory.GetFiles(Path, "*.7z", SearchOption.TopDirectoryOnly);
+ foreach (var file in files)
+ {
+ if (exec.Contains(System.IO.Path.GetFileName(file) + " "))
+ result.Add(file);
+ }
+ return result.ToArray();
+ }
+
+ public void Compress()
+ {
+ SevenZipExtractor.SetLibraryPath(System.IO.Path.Combine(Program.BaseDirectoryInternal, IntPtr.Size == 8 ? @"tools\7z64.dll" : @"tools\7z.dll"));
+ foreach (var filename in CompressPossible())
+ {
+ var archName = filename + ".7z";
+ var compressor = new SevenZipCompressor();
+ compressor.CompressionLevel = CompressionLevel.High;
+ Debug.WriteLine("Compressing " + filename);
+ compressor.CompressFiles(archName, filename);
+ File.Delete(filename);
+ Command = Command.Replace(System.IO.Path.GetFileName(filename), System.IO.Path.GetFileName(archName));
+ }
+ }
+
+ public void Decompress()
+ {
+ SevenZipExtractor.SetLibraryPath(System.IO.Path.Combine(Program.BaseDirectoryInternal, IntPtr.Size == 8 ? @"tools\7z64.dll" : @"tools\7z.dll"));
+ foreach (var filename in DecompressPossible())
+ {
+ using (var szExtractor = new SevenZipExtractor(filename))
+ {
+ Debug.WriteLine("Decompressing " + filename);
+ szExtractor.ExtractArchive(Path);
+ foreach (var f in szExtractor.ArchiveFileNames)
+ Command = Command.Replace(System.IO.Path.GetFileName(filename), f);
+ }
+ File.Delete(filename);
+ }
}
public class NesMiniAppEqualityComparer : IEqualityComparer<NesMiniApplication>
diff --git a/Apps/SnesGame.cs b/Apps/SnesGame.cs
index 2ff7cb99..49e3d365 100644
--- a/Apps/SnesGame.cs
+++ b/Apps/SnesGame.cs
@@ -1,6 +1,7 @@
#pragma warning disable 0108
using com.clusterrr.hakchi_gui.Properties;
using System.Drawing;
+using System.Windows.Forms;
namespace com.clusterrr.hakchi_gui
{
@@ -18,6 +19,14 @@ namespace com.clusterrr.hakchi_gui
: base(path, ignoreEmptyConfig)
{
}
+
+ public static NesMiniApplication Import(string fileName, string sourceFile = null, byte[] rawRomData = null)
+ {
+ if (ConfigIni.ConsoleType != MainForm.ConsoleType.SNES && ConfigIni.ConsoleType != MainForm.ConsoleType.SuperFamicom)
+ return null;
+
+ return null;
+ }
}
}