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:
-rw-r--r--FelLib/Fel.cs200
-rw-r--r--MainForm.cs26
-rw-r--r--MainForm.resx348
-rw-r--r--NesGame.cs7
-rw-r--r--Properties/AssemblyInfo.cs6
-rw-r--r--Properties/Resources.Designer.cs28
-rw-r--r--Properties/Resources.resx14
-rw-r--r--Properties/Resources.ru-RU.resx14
-rw-r--r--UnsupportedMapperException.cs17
-rw-r--r--WaitingForm.cs72
-rw-r--r--WaitingForm.resx33
-rw-r--r--WaitingForm.ru-RU.resx12
-rw-r--r--WorkerForm.cs261
-rw-r--r--hakchi_gui.csproj2
14 files changed, 524 insertions, 516 deletions
diff --git a/FelLib/Fel.cs b/FelLib/Fel.cs
index f0db341d..4a99bbb8 100644
--- a/FelLib/Fel.cs
+++ b/FelLib/Fel.cs
@@ -9,20 +9,40 @@ namespace com.clusterrr.FelLib
{
public class Fel
{
+ public byte[] Fes1Bin;
+ public byte[] UBootBin;
+
+ public enum CurrentAction { RunningCommand, ReadingMemory, WritingMemory }
+ public delegate void OnFelProgress(CurrentAction action, string command);
+
USBDevice device = null;
byte inEndp = 0;
byte outEndp = 0;
- const int ReadTimeout = 500;
+ const int ReadTimeout = 1000;
public const int MaxBulkSize = 0x10000;
UInt16 vid, pid;
+ bool DramInitDone = false;
+
+ const UInt32 cmdOffset = 0x604FF;
+ const UInt32 fes1_base_m = 0x2000;
+ const UInt32 dram_base = 0x40000000;
+ const UInt32 flash_mem_base = 0x43800000;
+ const UInt32 flash_mem_size = 0x20;
+ const UInt32 uboot_base_m = 0x47000000u;
+ const UInt32 sector_size = 0x20000;
+ const UInt32 uboot_base_f = 0x100000;
+ const UInt32 kernel_base_f = (sector_size * 0x30);
+ const UInt32 kernel_base_m = flash_mem_base;
+ const UInt32 kernel_max_size = (uboot_base_m - flash_mem_base);
+ const UInt32 kernel_max_flash_size = (sector_size * 0x20);
+ const string fastboot = "fastboot_test";
public static bool DeviceExists(UInt16 vid, UInt16 pid)
{
- var fel = new Fel();
+ var fel = new Fel();
try
{
fel.Open(vid, pid);
- fel.VerifyDevice();
return true;
}
catch
@@ -41,7 +61,7 @@ namespace com.clusterrr.FelLib
this.pid = pid;
Close();
device = USBDevice.GetSingleDevice(vid, pid);
- if (device == null) throw new Exception("Device not found");
+ if (device == null) throw new FelException("Device not found");
foreach (var pipe in device.Pipes)
{
if (pipe.IsIn)
@@ -51,6 +71,7 @@ namespace com.clusterrr.FelLib
}
device.Pipes[outEndp].Policy.PipeTransferTimeout = ReadTimeout;
ClearInputBuffer();
+ if (VerifyDevice().Board != 0x00166700) throw new FelException("Invalid board ID");
}
public void Close()
{
@@ -78,17 +99,19 @@ namespace com.clusterrr.FelLib
device.Pipes[outEndp].Write(buffer);
}
- private byte[] ReadFromUSB(UInt32 len)
+ private int ReadFromUSB(byte[] buffer, int offset, int length)
{
- var result = new List<byte>();
- while (result.Count < len)
+ return device.Pipes[inEndp].Read(buffer, offset, length);
+ }
+ private byte[] ReadFromUSB(UInt32 length)
+ {
+ var result = new byte[length];
+ int pos = 0;
+ while (pos < length)
{
- var buffer = new byte[len - result.Count];
- var l = device.Pipes[inEndp].Read(buffer);
- for (int i = 0; i < l && result.Count < len; i++)
- result.Add(buffer[i]);
+ pos += ReadFromUSB(result, pos, (int)(length - pos));
}
- return result.ToArray();
+ return result;
}
private void FelWrite(byte[] buffer)
@@ -102,14 +125,14 @@ namespace com.clusterrr.FelLib
if (resp.CswStatus != 0) throw new FelException("FEL write error");
}
- private byte[] FelRead(UInt32 len)
+ private byte[] FelRead(UInt32 length)
{
var req = new AWUSBRequest();
req.Cmd = AWUSBRequest.RequestType.AW_USB_READ;
- req.Len = len;
+ req.Len = length;
WriteToUSB(req.Data);
- var result = ReadFromUSB(len);
+ var result = ReadFromUSB(length);
var resp = new AWUSBResponse(ReadFromUSB(13));
if (resp.CswStatus != 0) throw new FelException("FEL read error");
return result;
@@ -139,14 +162,26 @@ namespace com.clusterrr.FelLib
return new AWFELVerifyDeviceResponse(resp);
}
- public void WriteMemory(UInt32 address, byte[] buffer)
+ public void WriteMemory(UInt32 address, byte[] buffer, OnFelProgress callback = null)
{
+ if (address >= dram_base)
+ InitDram();
+
+ UInt32 length = (UInt32)buffer.Length;
+ if (length != (length & ~((UInt32)3)))
+ {
+ length = (length + 3) & ~((UInt32)3);
+ var newBuffer = new byte[length];
+ Array.Copy(buffer, 0, newBuffer, 0, buffer.Length);
+ buffer = newBuffer;
+ }
+
int pos = 0;
while (pos < buffer.Length)
{
+ if (callback != null) callback(CurrentAction.WritingMemory, null);
var buf = new byte[Math.Min(buffer.Length - pos, MaxBulkSize)];
Array.Copy(buffer, pos, buf, 0, buf.Length);
-
FelRequest(AWFELStandardRequest.RequestType.FEL_DOWNLOAD, (UInt32)(address + pos), (uint)buf.Length);
FelWrite(buf);
var status = new AWFELStatusResponse(FelRead(8));
@@ -155,13 +190,18 @@ namespace com.clusterrr.FelLib
}
}
- public byte[] ReadMemory(UInt32 address, UInt32 length)
+ private byte[] ReadMemory(UInt32 address, UInt32 length, OnFelProgress callback = null)
{
+ if (address >= dram_base)
+ InitDram();
+
+ length = (length + 3) & ~((UInt32)3);
+
var result = new List<byte>();
while (length > 0)
{
+ if (callback != null) callback(CurrentAction.ReadingMemory, null);
var l = Math.Min(length, MaxBulkSize);
- Console.WriteLine("Reading {0:X8}, size: {1:X8}...", address, l);
FelRequest(AWFELStandardRequest.RequestType.FEL_UPLOAD, address, l);
var r = FelRead((UInt32)l);
result.AddRange(r);
@@ -173,28 +213,114 @@ namespace com.clusterrr.FelLib
return result.ToArray();
}
- public void Exec(UInt32 address, int pause = 0)
+ public bool InitDram(bool force = false)
+ {
+ if (DramInitDone && !force) return true;
+ if (DramInitDone) return true;
+ const UInt32 testSize = 0x80;
+ if (Fes1Bin == null || Fes1Bin.Length < testSize)
+ throw new FelException("Can't init DRAM, incorrect Fes1 binary");
+ var buf = ReadMemory((UInt32)(fes1_base_m + Fes1Bin.Length - testSize), testSize);
+ var buf2 = new byte[testSize];
+ Array.Copy(Fes1Bin, Fes1Bin.Length - buf.Length, buf2, 0, testSize);
+ if (buf.SequenceEqual(buf2))
+ {
+ return DramInitDone = true;
+ }
+ WriteMemory(fes1_base_m, Fes1Bin);
+ Exec(fes1_base_m);
+ Thread.Sleep(2000);
+ return DramInitDone = true;
+ }
+
+ public byte[] ReadFlash(UInt32 address, UInt32 length, OnFelProgress callback = null)
+ {
+ var result = new List<byte>();
+ while (((length + address % sector_size + sector_size - 1) / sector_size) > flash_mem_size)
+ {
+ var sectors = (length + address % sector_size + sector_size - 1) / sector_size - flash_mem_size;
+ var buf = ReadFlash(address, sectors * sector_size - address % sector_size, callback);
+ address += (uint)buf.Length;
+ length -= (uint)buf.Length;
+ result.AddRange(buf);
+ }
+ if (result.Count > 0) return result.ToArray();
+ var command = string.Format("sunxi_flash phy_read {0:x} {1:x} {2:x};{3}", flash_mem_base, address / sector_size, (length + address % sector_size + sector_size - 1) / sector_size, fastboot);
+ RunUbootCmd(command, false, callback);
+ result.AddRange(ReadMemory(flash_mem_base + address % sector_size, length, callback));
+ return result.ToArray();
+ }
+
+ public void WriteFlash(UInt32 address, byte[] buffer, OnFelProgress callback = null)
+ {
+ int length = buffer.Length;
+ int pos = 0;
+ if ((address % sector_size) != 0)
+ throw new FelException(string.Format("Invalid address to flash: 0x{0:X8}", address));
+ if ((length % sector_size) != 0)
+ throw new FelException(string.Format("Invalid length to flash: 0x{0:X8}", length));
+ byte[] newBuf;
+ while ((length / sector_size) > flash_mem_size)
+ {
+ var sectors = (length / sector_size) - flash_mem_size;
+ newBuf = new byte[sectors * sector_size];
+ Array.Copy(buffer, pos, newBuf, 0, newBuf.Length);
+ WriteFlash(address, newBuf, callback);
+ address += (UInt32)newBuf.Length;
+ length -= newBuf.Length;
+ pos += newBuf.Length;
+ }
+ newBuf = new byte[length - pos];
+ Array.Copy(buffer, pos, newBuf, 0, newBuf.Length);
+ WriteMemory(flash_mem_base, newBuf, callback);
+ var command = string.Format("sunxi_flash phy_write {0:x} {1:x} {2:x};{3}", flash_mem_base, address / sector_size, length / sector_size, fastboot);
+ RunUbootCmd(command, false, callback);
+ }
+
+ public void Exec(UInt32 address)
{
FelRequest(AWFELStandardRequest.RequestType.FEL_RUN, address, 0);
var status = new AWFELStatusResponse(FelRead(8));
if (status.State != 0) throw new FelException("FEL run error");
- //Close();
- Thread.Sleep(pause * 1000);
- //int errorCount = 0;
- //while (true)
- //{
- // try
- // {
- // Open(vid, pid);
- // return;
- // }
- // catch (Exception ex)
- // {
- // errorCount++;
- // if (errorCount >= 8)
- // throw ex;
- // }
- //}
+ }
+
+ public void RunUbootCmd(string command, bool noreturn = false, OnFelProgress callback = null)
+ {
+ if (callback != null) callback(CurrentAction.RunningCommand, command);
+ const UInt32 testSize = 0x20;
+ if (UBootBin == null || UBootBin.Length < testSize)
+ throw new FelException("Can't init Uboot, incorrect Uboot binary");
+ var buf = ReadMemory(uboot_base_m, testSize);
+ var buf2 = new byte[testSize];
+ Array.Copy(UBootBin, 0, buf2, 0, testSize);
+ if (!buf.SequenceEqual(buf2))
+ WriteMemory(uboot_base_m, UBootBin);
+ var cmdBuff = Encoding.ASCII.GetBytes(command + "\0");
+ WriteMemory((uint)(uboot_base_m + cmdOffset), cmdBuff);
+ Exec((uint)uboot_base_m);
+ if (noreturn) return;
+ Close();
+ for (int i = 0; i < 10; i++)
+ {
+ Thread.Sleep(1000);
+ if (callback != null) callback(CurrentAction.RunningCommand, command);
+ }
+ int errorCount = 0;
+ while (true)
+ {
+ try
+ {
+ Open(vid, pid);
+ break;
+ }
+ catch (Exception ex)
+ {
+ errorCount++;
+ if (errorCount >= 10)
+ throw ex;
+ Thread.Sleep(2000);
+ }
+ }
}
}
}
diff --git a/MainForm.cs b/MainForm.cs
index 2053f642..67ecb456 100644
--- a/MainForm.cs
+++ b/MainForm.cs
@@ -218,7 +218,7 @@ namespace com.clusterrr.hakchi_gui
SaveConfig();
}
- void RecalculateSelectedGames(int i = -1, bool v = false)
+ int RecalculateSelectedGames(int i = -1, bool v = false)
{
int c = 0;
foreach (var game in checkedListBoxGames.CheckedItems)
@@ -239,6 +239,7 @@ namespace com.clusterrr.hakchi_gui
else c -= 1;
}
toolStripStatusLabelSelected.Text = c + " " + Resources.GamesSelected;
+ return c;
}
private void checkedListBoxGames_ItemCheck(object sender, ItemCheckEventArgs e)
@@ -256,7 +257,17 @@ namespace com.clusterrr.hakchi_gui
{
try
{
- nesGame = new NesGame(GamesDir, file);
+ try
+ {
+ nesGame = new NesGame(GamesDir, file);
+ }
+ catch (UnsupportedMapperException ex)
+ {
+ if (MessageBox.Show(this, string.Format(Resources.MapperNotSupported, Path.GetFileName(file), ex.ROM.Mapper), Resources.AreYouSure, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
+ == System.Windows.Forms.DialogResult.Yes)
+ nesGame = new NesGame(GamesDir, file, true);
+ else continue;
+ }
Settings.Default.SelectedGames += ";" + nesGame.Code;
}
catch (Exception ex)
@@ -308,13 +319,20 @@ namespace com.clusterrr.hakchi_gui
}
private void buttonStart_Click(object sender, EventArgs e)
- {
+ {
SaveConfig();
- if (checkedListBoxGames.CheckedItems.Count == 0)
+ var gamesCount = RecalculateSelectedGames();
+ if (gamesCount == 0)
{
MessageBox.Show(Resources.SelectAtLeast, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
+ if (gamesCount > 97)
+ {
+ if (MessageBox.Show(Resources.ManyGames, Resources.AreYouSure, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
+ == System.Windows.Forms.DialogResult.No)
+ return;
+ }
if (/*!File.Exists(UBootDump) ||*/ !File.Exists(KernelDump))
{
if (MessageBox.Show(Resources.NoKernelWarning, Resources.NoKernel, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
diff --git a/MainForm.resx b/MainForm.resx
index d309e4e5..7825cdcd 100644
--- a/MainForm.resx
+++ b/MainForm.resx
@@ -121,37 +121,6 @@
<value>132, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- <data name="menuStrip.Location" type="System.Drawing.Point, System.Drawing">
- <value>0, 0</value>
- </data>
- <data name="menuStrip.Size" type="System.Drawing.Size, System.Drawing">
- <value>609, 24</value>
- </data>
- <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
- <data name="menuStrip.TabIndex" type="System.Int32, mscorlib">
- <value>1</value>
- </data>
- <data name="menuStrip.Text" xml:space="preserve">
- <value>menuStrip</value>
- </data>
- <data name="&gt;&gt;menuStrip.Name" xml:space="preserve">
- <value>menuStrip</value>
- </data>
- <data name="&gt;&gt;menuStrip.Type" xml:space="preserve">
- <value>System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;menuStrip.Parent" xml:space="preserve">
- <value>$this</value>
- </data>
- <data name="&gt;&gt;menuStrip.ZOrder" xml:space="preserve">
- <value>7</value>
- </data>
- <data name="fileToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
- <value>37, 20</value>
- </data>
- <data name="fileToolStripMenuItem.Text" xml:space="preserve">
- <value>&amp;File</value>
- </data>
<data name="addMoreGamesToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>165, 22</value>
</data>
@@ -164,11 +133,11 @@
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>&amp;Exit</value>
</data>
- <data name="kernelToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
- <value>52, 20</value>
+ <data name="fileToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
+ <value>37, 20</value>
</data>
- <data name="kernelToolStripMenuItem.Text" xml:space="preserve">
- <value>&amp;Kernel</value>
+ <data name="fileToolStripMenuItem.Text" xml:space="preserve">
+ <value>&amp;File</value>
</data>
<data name="dumpKernelToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>179, 22</value>
@@ -188,12 +157,43 @@
<data name="flashCustomKernelToolStripMenuItem.Text" xml:space="preserve">
<value>Flash custom kernel</value>
</data>
+ <data name="kernelToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
+ <value>52, 20</value>
+ </data>
+ <data name="kernelToolStripMenuItem.Text" xml:space="preserve">
+ <value>&amp;Kernel</value>
+ </data>
<data name="aboutToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>61, 20</value>
</data>
<data name="aboutToolStripMenuItem.Text" xml:space="preserve">
<value>&amp;About...</value>
</data>
+ <data name="menuStrip.Location" type="System.Drawing.Point, System.Drawing">
+ <value>0, 0</value>
+ </data>
+ <data name="menuStrip.Size" type="System.Drawing.Size, System.Drawing">
+ <value>609, 24</value>
+ </data>
+ <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <data name="menuStrip.TabIndex" type="System.Int32, mscorlib">
+ <value>1</value>
+ </data>
+ <data name="menuStrip.Text" xml:space="preserve">
+ <value>menuStrip</value>
+ </data>
+ <data name="&gt;&gt;menuStrip.Name" xml:space="preserve">
+ <value>menuStrip</value>
+ </data>
+ <data name="&gt;&gt;menuStrip.Type" xml:space="preserve">
+ <value>System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </data>
+ <data name="&gt;&gt;menuStrip.Parent" xml:space="preserve">
+ <value>$this</value>
+ </data>
+ <data name="&gt;&gt;menuStrip.ZOrder" xml:space="preserve">
+ <value>7</value>
+ </data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="checkedListBoxGames.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
@@ -225,234 +225,6 @@
<data name="groupBoxOptions.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Right</value>
</data>
- <data name="&gt;&gt;label6.Name" xml:space="preserve">
- <value>label6</value>
- </data>
- <data name="&gt;&gt;label6.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;label6.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;label6.ZOrder" xml:space="preserve">
- <value>0</value>
- </data>
- <data name="&gt;&gt;radioButtonTwoSim.Name" xml:space="preserve">
- <value>radioButtonTwoSim</value>
- </data>
- <data name="&gt;&gt;radioButtonTwoSim.Type" xml:space="preserve">
- <value>System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;radioButtonTwoSim.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;radioButtonTwoSim.ZOrder" xml:space="preserve">
- <value>1</value>
- </data>
- <data name="&gt;&gt;buttonGoogle.Name" xml:space="preserve">
- <value>buttonGoogle</value>
- </data>
- <data name="&gt;&gt;buttonGoogle.Type" xml:space="preserve">
- <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;buttonGoogle.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;buttonGoogle.ZOrder" xml:space="preserve">
- <value>2</value>
- </data>
- <data name="&gt;&gt;buttonBrowseImage.Name" xml:space="preserve">
- <value>buttonBrowseImage</value>
- </data>
- <data name="&gt;&gt;buttonBrowseImage.Type" xml:space="preserve">
- <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;buttonBrowseImage.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;buttonBrowseImage.ZOrder" xml:space="preserve">
- <value>3</value>
- </data>
- <data name="&gt;&gt;pictureBoxArt.Name" xml:space="preserve">
- <value>pictureBoxArt</value>
- </data>
- <data name="&gt;&gt;pictureBoxArt.Type" xml:space="preserve">
- <value>System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;pictureBoxArt.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;pictureBoxArt.ZOrder" xml:space="preserve">
- <value>4</value>
- </data>
- <data name="&gt;&gt;label4.Name" xml:space="preserve">
- <value>label4</value>
- </data>
- <data name="&gt;&gt;label4.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;label4.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;label4.ZOrder" xml:space="preserve">
- <value>5</value>
- </data>
- <data name="&gt;&gt;textBoxArguments.Name" xml:space="preserve">
- <value>textBoxArguments</value>
- </data>
- <data name="&gt;&gt;textBoxArguments.Type" xml:space="preserve">
- <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;textBoxArguments.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;textBoxArguments.ZOrder" xml:space="preserve">
- <value>6</value>
- </data>
- <data name="&gt;&gt;label3.Name" xml:space="preserve">
- <value>label3</value>
- </data>
- <data name="&gt;&gt;label3.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;label3.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;label3.ZOrder" xml:space="preserve">
- <value>7</value>
- </data>
- <data name="&gt;&gt;textBoxPublisher.Name" xml:space="preserve">
- <value>textBoxPublisher</value>
- </data>
- <data name="&gt;&gt;textBoxPublisher.Type" xml:space="preserve">
- <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;textBoxPublisher.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;textBoxPublisher.ZOrder" xml:space="preserve">
- <value>8</value>
- </data>
- <data name="&gt;&gt;label2.Name" xml:space="preserve">
- <value>label2</value>
- </data>
- <data name="&gt;&gt;label2.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;label2.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;label2.ZOrder" xml:space="preserve">
- <value>9</value>
- </data>
- <data name="&gt;&gt;maskedTextBoxReleaseDate.Name" xml:space="preserve">
- <value>maskedTextBoxReleaseDate</value>
- </data>
- <data name="&gt;&gt;maskedTextBoxReleaseDate.Type" xml:space="preserve">
- <value>System.Windows.Forms.MaskedTextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;maskedTextBoxReleaseDate.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;maskedTextBoxReleaseDate.ZOrder" xml:space="preserve">
- <value>10</value>
- </data>
- <data name="&gt;&gt;label1.Name" xml:space="preserve">
- <value>label1</value>
- </data>
- <data name="&gt;&gt;label1.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;label1.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
- <value>11</value>
- </data>
- <data name="&gt;&gt;radioButtonTwo.Name" xml:space="preserve">
- <value>radioButtonTwo</value>
- </data>
- <data name="&gt;&gt;radioButtonTwo.Type" xml:space="preserve">
- <value>System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;radioButtonTwo.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;radioButtonTwo.ZOrder" xml:space="preserve">
- <value>12</value>
- </data>
- <data name="&gt;&gt;radioButtonOne.Name" xml:space="preserve">
- <value>radioButtonOne</value>
- </data>
- <data name="&gt;&gt;radioButtonOne.Type" xml:space="preserve">
- <value>System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;radioButtonOne.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;radioButtonOne.ZOrder" xml:space="preserve">
- <value>13</value>
- </data>
- <data name="&gt;&gt;textBoxName.Name" xml:space="preserve">
- <value>textBoxName</value>
- </data>
- <data name="&gt;&gt;textBoxName.Type" xml:space="preserve">
- <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;textBoxName.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;textBoxName.ZOrder" xml:space="preserve">
- <value>14</value>
- </data>
- <data name="&gt;&gt;labelName.Name" xml:space="preserve">
- <value>labelName</value>
- </data>
- <data name="&gt;&gt;labelName.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;labelName.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;labelName.ZOrder" xml:space="preserve">
- <value>15</value>
- </data>
- <data name="&gt;&gt;labelID.Name" xml:space="preserve">
- <value>labelID</value>
- </data>
- <data name="&gt;&gt;labelID.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;labelID.Parent" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;labelID.ZOrder" xml:space="preserve">
- <value>16</value>
- </data>
- <data name="groupBoxOptions.Location" type="System.Drawing.Point, System.Drawing">
- <value>306, 27</value>
- </data>
- <data name="groupBoxOptions.Size" type="System.Drawing.Size, System.Drawing">
- <value>293, 500</value>
- </data>
- <data name="groupBoxOptions.TabIndex" type="System.Int32, mscorlib">
- <value>3</value>
- </data>
- <data name="groupBoxOptions.Text" xml:space="preserve">
- <value>Game options</value>
- </data>
- <data name="&gt;&gt;groupBoxOptions.Name" xml:space="preserve">
- <value>groupBoxOptions</value>
- </data>
- <data name="&gt;&gt;groupBoxOptions.Type" xml:space="preserve">
- <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </data>
- <data name="&gt;&gt;groupBoxOptions.Parent" xml:space="preserve">
- <value>$this</value>
- </data>
- <data name="&gt;&gt;groupBoxOptions.ZOrder" xml:space="preserve">
- <value>5</value>
- </data>
<data name="label6.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
@@ -885,6 +657,30 @@
<data name="&gt;&gt;labelID.ZOrder" xml:space="preserve">
<value>16</value>
</data>
+ <data name="groupBoxOptions.Location" type="System.Drawing.Point, System.Drawing">
+ <value>306, 27</value>
+ </data>
+ <data name="groupBoxOptions.Size" type="System.Drawing.Size, System.Drawing">
+ <value>293, 500</value>
+ </data>
+ <data name="groupBoxOptions.TabIndex" type="System.Int32, mscorlib">
+ <value>3</value>
+ </data>
+ <data name="groupBoxOptions.Text" xml:space="preserve">
+ <value>Game options</value>
+ </data>
+ <data name="&gt;&gt;groupBoxOptions.Name" xml:space="preserve">
+ <value>groupBoxOptions</value>
+ </data>
+ <data name="&gt;&gt;groupBoxOptions.Type" xml:space="preserve">
+ <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </data>
+ <data name="&gt;&gt;groupBoxOptions.Parent" xml:space="preserve">
+ <value>$this</value>
+ </data>
+ <data name="&gt;&gt;groupBoxOptions.ZOrder" xml:space="preserve">
+ <value>5</value>
+ </data>
<data name="label5.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
@@ -942,6 +738,12 @@
<metadata name="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>350, 17</value>
</metadata>
+ <data name="toolStripStatusLabelSelected.Size" type="System.Drawing.Size, System.Drawing">
+ <value>118, 17</value>
+ </data>
+ <data name="toolStripStatusLabelSelected.Text" xml:space="preserve">
+ <value>toolStripStatusLabel1</value>
+ </data>
<data name="statusStrip.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 579</value>
</data>
@@ -966,12 +768,6 @@
<data name="&gt;&gt;statusStrip.ZOrder" xml:space="preserve">
<value>2</value>
</data>
- <data name="toolStripStatusLabelSelected.Size" type="System.Drawing.Size, System.Drawing">
- <value>118, 17</value>
- </data>
- <data name="toolStripStatusLabelSelected.Text" xml:space="preserve">
- <value>toolStripStatusLabel1</value>
- </data>
<metadata name="openFileDialogNes.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>459, 17</value>
</metadata>
@@ -984,6 +780,12 @@
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>592, 17</value>
</metadata>
+ <data name="deleteGameToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
+ <value>140, 22</value>
+ </data>
+ <data name="deleteGameToolStripMenuItem.Text" xml:space="preserve">
+ <value>Delete game</value>
+ </data>
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>141, 26</value>
</data>
@@ -993,12 +795,6 @@
<data name="&gt;&gt;contextMenuStrip.Type" xml:space="preserve">
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
- <data name="deleteGameToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
- <value>140, 22</value>
- </data>
- <data name="deleteGameToolStripMenuItem.Text" xml:space="preserve">
- <value>Delete game</value>
- </data>
<metadata name="openFileDialogImage.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>741, 17</value>
</metadata>
@@ -2180,7 +1976,7 @@
<value>CenterScreen</value>
</data>
<data name="$this.Text" xml:space="preserve">
- <value>hakchi2 - NES Mini pimp tool, v2.01 beta</value>
+ <value>hakchi2 - NES Mini pimp tool, v2.02 beta</value>
</data>
<data name="&gt;&gt;fileToolStripMenuItem.Name" xml:space="preserve">
<value>fileToolStripMenuItem</value>
diff --git a/NesGame.cs b/NesGame.cs
index 27fd97e0..6f16095a 100644
--- a/NesGame.cs
+++ b/NesGame.cs
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+using System.Windows.Forms;
namespace com.clusterrr.hakchi_gui
{
@@ -132,12 +133,12 @@ namespace com.clusterrr.hakchi_gui
Code, Args, Name, Players, ReleaseDate, Name.ToLower(), Publisher.ToUpper(), Simultaneous ? 1 : 0));
}
- public NesGame(string gamesDirectory, string nesFileName)
+ public NesGame(string gamesDirectory, string nesFileName, bool ignoreMapper = false)
{
var nesFile = new NesFile(nesFileName);
nesFile.CorrectRom();
- if (!supportedMappers.Contains(nesFile.Mapper))
- throw new Exception(string.Format(Resources.MapperNotSupported, Path.GetFileName(nesFileName), nesFile.Mapper));
+ if (!supportedMappers.Contains(nesFile.Mapper) && !ignoreMapper)
+ throw new UnsupportedMapperException(nesFile);
Code = string.Format("CLV-H-{0}{1}{2}{3}{4}",
(char)('A' + (nesFile.CRC32 % 26)),
(char)('A' + (nesFile.CRC32 >> 5) % 26),
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
index 7059ea81..97e3827a 100644
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("hakchi2")]
-[assembly: AssemblyDescription("Based on hakchi by madmonkey\r\n\r\nSpetial thanks:\r\nPete Batard/Akeo for Zadig\r\npbatard for libwdi\r\nNintendo for my childhood\r\n\r\nMy site: http://clusterrr.com\r\nE-mail: clusterrr@clusterrr.com")]
+[assembly: AssemblyDescription("Based on hakchi by madmonkey\r\n\r\nSpetial thanks:\r\nPete Batard/Akeo for Zadig\r\npbatard for libwdi\r\nThomas Bleeker for WinUSBNet library\r\nNintendo for my childhood\r\n\r\nMy site: http://clusterrr.com\r\nE-mail: clusterrr@clusterrr.com\r\nPayPal for donations: clusterrr@clusterrr.com")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Alexey 'Cluster' Avrdyukhin")]
[assembly: AssemblyProduct("hakchi2")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.0.0")]
-[assembly: AssemblyFileVersion("2.0.0.1")]
+[assembly: AssemblyVersion("2.0.0.2")]
+[assembly: AssemblyFileVersion("2.0.0.2")]
diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs
index 9119b500..f6f85f14 100644
--- a/Properties/Resources.Designer.cs
+++ b/Properties/Resources.Designer.cs
@@ -224,7 +224,7 @@ namespace com.clusterrr.hakchi_gui.Properties {
}
/// <summary>
- /// Looks up a localized string similar to Executing fel1....
+ /// Looks up a localized string similar to Executing fes1....
/// </summary>
internal static string ExecutingFel1 {
get {
@@ -288,7 +288,16 @@ namespace com.clusterrr.hakchi_gui.Properties {
}
/// <summary>
- /// Looks up a localized string similar to Sorry, {0} uses mapper #{1}, it&apos;s is not supported..
+ /// Looks up a localized string similar to NES Mini can handle only 97 games but you selected {0} games. Do you want to continue?.
+ /// </summary>
+ internal static string ManyGames {
+ get {
+ return ResourceManager.GetString("ManyGames", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Sorry, {0} uses mapper #{1} but this mapper not supported by NES Mini and game probably will not start. Do you want to add this game anyway?.
/// </summary>
internal static string MapperNotSupported {
get {
@@ -360,6 +369,15 @@ namespace com.clusterrr.hakchi_gui.Properties {
}
/// <summary>
+ /// Looks up a localized string similar to If problem repeats try to use another USB port or another USB cable..
+ /// </summary>
+ internal static string PleaseTryAgainUSB {
+ get {
+ return ResourceManager.GetString("PleaseTryAgainUSB", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Press OK to continue..
/// </summary>
internal static string PressOkToContinue {
@@ -397,11 +415,11 @@ namespace com.clusterrr.hakchi_gui.Properties {
}
/// <summary>
- /// Looks up a localized string similar to Uploading fel1....
+ /// Looks up a localized string similar to Uploading and running fes1....
/// </summary>
- internal static string UploadingFel1 {
+ internal static string UploadingFes1 {
get {
- return ResourceManager.GetString("UploadingFel1", resourceCulture);
+ return ResourceManager.GetString("UploadingFes1", resourceCulture);
}
}
diff --git a/Properties/Resources.resx b/Properties/Resources.resx
index 9c165ab8..217426ae 100644
--- a/Properties/Resources.resx
+++ b/Properties/Resources.resx
@@ -173,7 +173,7 @@
<value>Executing command:</value>
</data>
<data name="ExecutingFel1" xml:space="preserve">
- <value>Executing fel1...</value>
+ <value>Executing fes1...</value>
</data>
<data name="fes1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\fes1.bin;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
@@ -194,7 +194,7 @@
<value>Invalid kernel size:</value>
</data>
<data name="MapperNotSupported" xml:space="preserve">
- <value>Sorry, {0} uses mapper #{1}, it's is not supported.</value>
+ <value>Sorry, {0} uses mapper #{1} but this mapper not supported by NES Mini and game probably will not start. Do you want to add this game anyway?</value>
</data>
<data name="MD5Failed" xml:space="preserve">
<value>Kernel dumped but MD5 checksum is unknown: {0}</value>
@@ -229,8 +229,8 @@
<data name="uboot" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\uboot.bin;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
- <data name="UploadingFel1" xml:space="preserve">
- <value>Uploading fel1...</value>
+ <data name="UploadingFes1" xml:space="preserve">
+ <value>Uploading and running fes1...</value>
</data>
<data name="UploadingGames" xml:space="preserve">
<value>Uploading games...</value>
@@ -256,4 +256,10 @@
<data name="Wow" xml:space="preserve">
<value>Wow</value>
</data>
+ <data name="ManyGames" xml:space="preserve">
+ <value>NES Mini can handle only 97 games but you selected {0} games. Do you want to continue?</value>
+ </data>
+ <data name="PleaseTryAgainUSB" xml:space="preserve">
+ <value>If problem repeats try to use another USB port or another USB cable.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/Properties/Resources.ru-RU.resx b/Properties/Resources.ru-RU.resx
index 1798cc85..e70c549c 100644
--- a/Properties/Resources.ru-RU.resx
+++ b/Properties/Resources.ru-RU.resx
@@ -170,7 +170,7 @@
<value>Выполняем команду:</value>
</data>
<data name="ExecutingFel1" xml:space="preserve">
- <value>Запускаем fel1...</value>
+ <value>Запускаем fes1...</value>
</data>
<data name="fes1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\fes1.bin;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
@@ -223,8 +223,8 @@
<data name="uboot" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\uboot.bin;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
- <data name="UploadingFel1" xml:space="preserve">
- <value>Загружаем fel1...</value>
+ <data name="UploadingFes1" xml:space="preserve">
+ <value>Загружаем и выполняем fes1...</value>
</data>
<data name="UploadingGames" xml:space="preserve">
<value>Загружаем игры...</value>
@@ -254,6 +254,12 @@
<value>Пропатченное ядро</value>
</data>
<data name="MapperNotSupported" xml:space="preserve">
- <value>Увы, {0} использует маппер #{1}, а он не поддерживается.</value>
+ <value>Увы, {0} использует маппер #{1}, а NES Mini его вроде как не поддерживает, и игра скорее всего не запустится. Всё равно добавить?</value>
+ </data>
+ <data name="ManyGames" xml:space="preserve">
+ <value>Говорят, что NES Mini может выдержать только 97 игр, а у вас их {0}. Продолжить?</value>
+ </data>
+ <data name="PleaseTryAgainUSB" xml:space="preserve">
+ <value>Если проблема повторяется, попробуйте другой USB порт или другой USB кабель.</value>
</data>
</root> \ No newline at end of file
diff --git a/UnsupportedMapperException.cs b/UnsupportedMapperException.cs
new file mode 100644
index 00000000..5929114a
--- /dev/null
+++ b/UnsupportedMapperException.cs
@@ -0,0 +1,17 @@
+using com.clusterrr.Famicom;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace com.clusterrr.hakchi_gui
+{
+ public class UnsupportedMapperException : Exception
+ {
+ public readonly NesFile ROM;
+ public UnsupportedMapperException(NesFile nesFile)
+ {
+ ROM = nesFile;
+ }
+ }
+}
diff --git a/WaitingForm.cs b/WaitingForm.cs
index 24218086..082b9cfd 100644
--- a/WaitingForm.cs
+++ b/WaitingForm.cs
@@ -8,7 +8,9 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Management;
using System.Text;
+using System.Threading;
using System.Windows.Forms;
namespace com.clusterrr.hakchi_gui
@@ -27,21 +29,33 @@ namespace com.clusterrr.hakchi_gui
public static bool WaitForDevice(UInt16 vid, UInt16 pid)
{
- if (!Fel.DeviceExists(vid, pid))
- {
- var form = new WaitingForm(vid, pid);
- form.ShowDialog();
- return form.DialogResult == DialogResult.OK;
- }
- return true;
+ if (/*DeviceExists(vid, pid) &&*/ Fel.DeviceExists(vid, pid)) return true;
+ var form = new WaitingForm(vid, pid);
+ form.ShowDialog();
+ return form.DialogResult == DialogResult.OK;
+ }
+
+ static bool DeviceExists(UInt16 vid, UInt16 pid)
+ {
+ var devices = GetUSBDevices();
+ var id = string.Format("VID_{0:X4}&PID_{1:X4}", vid, pid);
+ foreach (var device in devices)
+ {
+ if (device.DeviceID.Contains(id))
+ return true;
+ }
+ return false;
}
private void timer_Tick(object sender, EventArgs e)
{
- if (Fel.DeviceExists(vid, pid))
+ //if (DeviceExists(vid, pid))
{
- DialogResult = DialogResult.OK;
- timer.Enabled = false;
+ if (Fel.DeviceExists(vid, pid))
+ {
+ DialogResult = DialogResult.OK;
+ timer.Enabled = false;
+ }
}
}
@@ -77,7 +91,43 @@ namespace com.clusterrr.hakchi_gui
private void WaitingForm_FormClosed(object sender, FormClosedEventArgs e)
{
timer.Enabled = false;
- }
+ }
+
+
+ static List<USBDeviceInfo> GetUSBDevices()
+ {
+ List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
+
+ ManagementObjectCollection collection;
+ using (var searcher = new ManagementObjectSearcher(@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""))
+ collection = searcher.Get();
+
+ foreach (var device in collection)
+ {
+ devices.Add(new USBDeviceInfo(
+ (string)device.GetPropertyValue("DeviceID"),
+ (string)device.GetPropertyValue("PNPDeviceID"),
+ (string)device.GetPropertyValue("Description")
+ ));
+ }
+
+ collection.Dispose();
+ return devices;
+ }
}
+ class USBDeviceInfo
+ {
+ public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
+ {
+ this.DeviceID = deviceID;
+ this.PnpDeviceID = pnpDeviceID;
+ this.Description = description;
+ }
+ public string DeviceID { get; private set; }
+ public string PnpDeviceID { get; private set; }
+ public string Description { get; private set; }
+ }
}
+
+
diff --git a/WaitingForm.resx b/WaitingForm.resx
index be092e4c..d5aaa837 100644
--- a/WaitingForm.resx
+++ b/WaitingForm.resx
@@ -140,7 +140,7 @@
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="label5.Location" type="System.Drawing.Point, System.Drawing">
- <value>23, 150</value>
+ <value>16, 150</value>
</data>
<data name="buttonDriver.Size" type="System.Drawing.Size, System.Drawing">
<value>169, 23</value>
@@ -153,10 +153,7 @@
<value>3</value>
</data>
<data name="label6.Location" type="System.Drawing.Point, System.Drawing">
- <value>23, 180</value>
- </data>
- <data name="label2.AutoSize" type="System.Boolean, mscorlib">
- <value>True</value>
+ <value>16, 180</value>
</data>
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
<value>261, 13</value>
@@ -184,13 +181,13 @@
<value>$this</value>
</data>
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
- <value>23, 90</value>
+ <value>16, 90</value>
</data>
<data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
<value>6</value>
</data>
<data name="buttonDriver.Location" type="System.Drawing.Point, System.Drawing">
- <value>206, 175</value>
+ <value>199, 175</value>
</data>
<data name="&gt;&gt;label4.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
@@ -261,7 +258,10 @@
<data name="&gt;&gt;label2.Parent" xml:space="preserve">
<value>$this</value>
</data>
- <data name="label5.AutoSize" type="System.Boolean, mscorlib">
+ <data name="&gt;&gt;label1.Type" xml:space="preserve">
+ <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </data>
+ <data name="label2.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
@@ -271,10 +271,10 @@
<value>label2</value>
</data>
<data name="label5.Text" xml:space="preserve">
- <value>4. After few seconds release the reset button, power led should not be on</value>
+ <value>4. After few seconds release the RESET button, POWER led should not be on</value>
</data>
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
- <value>23, 22</value>
+ <value>16, 22</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>Waiting for NES Mini...</value>
@@ -292,16 +292,16 @@
<value>Install driver</value>
</data>
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
- <value>23, 60</value>
+ <value>16, 60</value>
</data>
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
- <value>23, 120</value>
+ <value>16, 120</value>
</data>
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
<value>258, 13</value>
</data>
<data name="label5.Size" type="System.Drawing.Size, System.Drawing">
- <value>352, 13</value>
+ <value>377, 13</value>
</data>
<data name="label6.Size" type="System.Drawing.Size, System.Drawing">
<value>177, 13</value>
@@ -318,8 +318,8 @@
<data name="&gt;&gt;buttonDriver.Parent" xml:space="preserve">
<value>$this</value>
</data>
- <data name="&gt;&gt;label1.Type" xml:space="preserve">
- <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ <data name="label5.AutoSize" type="System.Boolean, mscorlib">
+ <value>True</value>
</data>
<data name="&gt;&gt;label6.Name" xml:space="preserve">
<value>label6</value>
@@ -333,9 +333,6 @@
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
- <metadata name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
- <value>ru-RU</value>
- </metadata>
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
diff --git a/WaitingForm.ru-RU.resx b/WaitingForm.ru-RU.resx
index 6fb39b6f..8a20b932 100644
--- a/WaitingForm.ru-RU.resx
+++ b/WaitingForm.ru-RU.resx
@@ -125,10 +125,10 @@
<value>Пожалуйста, выполните следующие шаги:</value>
</data>
<data name="label2.Size" type="System.Drawing.Size, System.Drawing">
- <value>237, 13</value>
+ <value>239, 13</value>
</data>
<data name="label2.Text" xml:space="preserve">
- <value>1. Убедитесь, что кнопка "power" выключена</value>
+ <value>1. Убедитесь, что кнопка POWER выключена</value>
</data>
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
<value>272, 13</value>
@@ -137,16 +137,16 @@
<value>2. (Пере)подключите NES Mini к компьютеру по USB</value>
</data>
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
- <value>276, 13</value>
+ <value>281, 13</value>
</data>
<data name="label4.Text" xml:space="preserve">
- <value>3. Зажмите кнопку "reset" и нажмите кнопку "power"</value>
+ <value>3. Зажмите кнопку RESET и нажмите кнопку POWER</value>
</data>
<data name="label5.Size" type="System.Drawing.Size, System.Drawing">
- <value>356, 13</value>
+ <value>359, 13</value>
</data>
<data name="label5.Text" xml:space="preserve">
- <value>4. Через папу секунд отпустите "reset", светодиод не должен гореть</value>
+ <value>4. Через папу секунд отпустите RESET, светодиод не должен гореть</value>
</data>
<data name="label6.Size" type="System.Drawing.Size, System.Drawing">
<value>275, 13</value>
diff --git a/WorkerForm.cs b/WorkerForm.cs
index 820dff60..549c92da 100644
--- a/WorkerForm.cs
+++ b/WorkerForm.cs
@@ -72,7 +72,7 @@ namespace com.clusterrr.hakchi_gui
kernelPatched = Path.Combine(kernelDirectory, "patched_kernel.img");
ramdiskPatched = Path.Combine(kernelDirectory, "kernel.img-ramdisk_mod.gz");
configPath = Path.Combine(hakchiDirectory, "config");
- correctKernels = new string[] { "5cfdca351484e7025648abc3b20032ff", "07bfb800beba6ef619c29990d14b5158" };
+ correctKernels = new string[] { "5cfdca351484e7025648abc3b20032ff", "07bfb800beba6ef619c29990d14b5158", };
gamesDirectory = Path.Combine(ramfsDirectory, "games");
}
@@ -92,9 +92,14 @@ namespace com.clusterrr.hakchi_gui
public void StartThread()
{
fel = new Fel();
+ fel.Fes1Bin = Resources.fes1;
+ fel.UBootBin = Resources.uboot;
+ SetProgress(0, 100);
try
{
fel.Open(vid, pid);
+ SetStatus(Resources.UploadingFes1);
+ fel.InitDram(true);
switch (Task)
{
case Tasks.DumpKernel:
@@ -113,11 +118,13 @@ namespace com.clusterrr.hakchi_gui
Memboot();
break;
}
+ Thread.Sleep(1000);
+ DialogResult = DialogResult.OK;
}
catch (ThreadAbortException) { }
catch (Exception ex)
{
- ShowError(ex.Message);
+ ShowError(ex);
}
finally
{
@@ -144,6 +151,7 @@ namespace com.clusterrr.hakchi_gui
}
catch { }
}
+
void SetStatus(string status)
{
if (Disposing) return;
@@ -158,6 +166,7 @@ namespace com.clusterrr.hakchi_gui
}
catch { }
}
+
void SetProgress(int value, int max)
{
if (Disposing) return;
@@ -175,104 +184,62 @@ namespace com.clusterrr.hakchi_gui
catch { }
}
- void ShowError(string text)
+ void ShowError(Exception ex)
{
if (Disposing) return;
try
{
if (InvokeRequired)
{
- Invoke(new Action<string>(ShowError), new object[] { text });
+ Invoke(new Action<Exception>(ShowError), new object[] { ex });
return;
}
- MessageBox.Show(this, text + "\r\n" + Resources.PleaseTryAgain, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ if (ex is MadWizard.WinUSBNet.USBException)
+ MessageBox.Show(this, ex.Message + "\r\n" + Resources.PleaseTryAgain + "\r\n" + Resources.PleaseTryAgainUSB, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ else
+ MessageBox.Show(this, ex.Message + "\r\n" + Resources.PleaseTryAgain, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
thread = null;
Close();
}
catch { }
}
- void ExecCommand(string command, bool nopause = false)
+ public void DoKernelDump()
{
- SetStatus(Resources.ExecutingCommand + " " + command);
- fel.WriteMemory((uint)(uboot_base_m + cmdOffset), Encoding.ASCII.GetBytes(command + "\0"));
- fel.Exec((uint)uboot_base_m, nopause ? 0 : 10);
- }
+ int progress = 5;
+ const int maxProgress = 80;
+ SetProgress(progress, maxProgress);
+ SetStatus(Resources.DumpingKernel);
- byte[] WaitRead(UInt32 address, UInt32 size)
- {
- SetStatus(Resources.WaitingForDevice);
- int errorCount = 0;
- while (true)
- {
- try
+ var kernel = fel.ReadFlash(kernel_base_f, sector_size * 0x20,
+ delegate(Fel.CurrentAction action, string command)
{
- if ((errorCount > 0) && (errorCount % 5) == 0)
+ switch (action)
{
- fel.Close();
- Thread.Sleep(1000);
- fel.Open(vid, pid);
+ case Fel.CurrentAction.RunningCommand:
+ SetStatus(Resources.ExecutingCommand + " " + command);
+ break;
+ case Fel.CurrentAction.ReadingMemory:
+ SetStatus(Resources.DumpingKernel);
+ break;
}
- fel.ClearInputBuffer();
- fel.VerifyDevice();
- var data = fel.ReadMemory(address, size);
- return data;
- }
- catch (Exception ex)
- {
- errorCount++;
- if (errorCount >= 15) throw ex;
- Thread.Sleep(1000);
+ progress++;
+ SetProgress(progress, maxProgress);
}
- }
- }
+ );
- public void DoKernelDump()
- {
- const int maxProgress = 100;
- SetProgress(1, maxProgress);
- SetStatus(Resources.UploadingFel1);
- fel.WriteMemory((uint)fes1_base_m, Resources.fes1);
- SetProgress(10, maxProgress);
- //Console.WriteLine("OK");
- //var r = fel.ReadMemory(0x2000, (UInt32)fel1.Length);
- SetStatus(Resources.ExecutingFel1);
- fel.Exec((uint)fes1_base_m, 3);
- SetProgress(20, maxProgress);
- SetStatus(Resources.UploadingUboot);
- fel.WriteMemory(uboot_base_m, Resources.uboot);
- SetProgress(30, maxProgress);
- /*
- var addr = 0x100000;
- UInt32 size = sector_size * 6;
- var command = string.Format("sunxi_flash phy_read {0:x} {1:x} {2:x};fastboot_test", flash_mem_base, addr / sector_size, (size + addr % sector_size + sector_size - 1) / sector_size);
- ExecCommand(command);
- SetProgress(50, maxDumpProgress);
- var header = WaitRead(flash_mem_base, 32);
- SetProgress(70, maxDumpProgress);
- size = (UInt32)(header[0x14] | (header[0x15] * 0x100) | (header[0x16] * 0x10000) | (header[0x17] * 0x1000000));
- if (size == 0 || size > kernel_max_size)
- throw new Exception("Invalid uboot size: " + size);
- SetStatus("Dumping uboot...");
- var uboot = fel.ReadMemory(flash_mem_base, size);
- Directory.CreateDirectory(Path.GetDirectoryName(UBootDump));
- File.WriteAllBytes(UBootDump, uboot);
- SetProgress(90, maxDumpProgress);
- */
-
- var addr = 0x600000;
- var size = sector_size * 0x20;
- var command = string.Format("sunxi_flash phy_read {0:x} {1:x} {2:x};fastboot_test", flash_mem_base, addr / sector_size, (size + addr % sector_size + sector_size - 1) / sector_size);
- ExecCommand(command);
- SetProgress(50, maxProgress);
- var header = WaitRead(flash_mem_base, 64);
- SetProgress(70, maxProgress);
-
- size = CalKernelSize(header);
+ var size = CalKernelSize(kernel);
if (size == 0 || size > kernel_max_size)
throw new Exception(Resources.InvalidKernelSize + " " + size);
- SetStatus(Resources.DumpingKernel);
- var kernel = fel.ReadMemory(flash_mem_base, size);
+ if (kernel.Length > size)
+ {
+ var sm_kernel = new byte[size];
+ Array.Copy(kernel, 0, sm_kernel, 0, size);
+ kernel = sm_kernel;
+ }
+
+ SetProgress(maxProgress, maxProgress);
+ SetStatus(Resources.Done);
var md5 = System.Security.Cryptography.MD5.Create();
var hash = BitConverter.ToString(md5.ComputeHash(kernel)).Replace("-", "").ToLower();
@@ -288,25 +255,27 @@ namespace com.clusterrr.hakchi_gui
Directory.CreateDirectory(Path.GetDirectoryName(KernelDump));
File.WriteAllBytes(KernelDump, kernel);
- SetProgress(maxProgress, maxProgress);
- SetStatus(Resources.Done);
- Thread.Sleep(1000);
- DialogResult = DialogResult.OK;
}
public void FlashKernel()
{
- const int maxProgress = 180;
- SetProgress(0, maxProgress);
+ int progress = 5;
+ int maxProgress = 120 + (string.IsNullOrEmpty(Mod) ? 0 : 5);
+ SetProgress(progress, maxProgress);
byte[] kernel;
if (!string.IsNullOrEmpty(Mod))
+ {
kernel = CreatePatchedKernel(Mod);
+ progress += 5;
+ SetProgress(progress, maxProgress);
+ }
else
kernel = File.ReadAllBytes(KernelDump);
var size = CalKernelSize(kernel);
if (size > kernel.Length || size > kernel_max_size)
throw new Exception(Resources.InvalidKernelSize + " " + size);
+
size = (size + sector_size - 1) / sector_size;
size = size * sector_size;
if (kernel.Length != size)
@@ -315,56 +284,56 @@ namespace com.clusterrr.hakchi_gui
Array.Copy(kernel, newK, kernel.Length);
kernel = newK;
}
- SetProgress(20, maxProgress);
-
- fel.Open(vid, pid);
- SetStatus(Resources.UploadingFel1);
- fel.WriteMemory((uint)fes1_base_m, Resources.fes1);
- SetProgress(30, maxProgress);
- //Console.WriteLine("OK");
- //var r = fel.ReadMemory(0x2000, (UInt32)fel1.Length);
- SetStatus(Resources.ExecutingFel1);
- fel.Exec((uint)fes1_base_m, 3);
- Thread.Sleep(3000);
- SetProgress(40, maxProgress);
- SetStatus(Resources.UploadingUboot);
- fel.WriteMemory(uboot_base_m, Resources.uboot);
- SetProgress(50, maxProgress);
- SetStatus(Resources.UploadingKernel);
- fel.WriteMemory(flash_mem_base, kernel);
- SetProgress(80, maxProgress);
- var addr = 0x600000;
- var command = string.Format("sunxi_flash phy_write {0:x} {1:x} {2:x};fastboot_test", flash_mem_base, addr / sector_size, size / sector_size);
- ExecCommand(command);
- SetProgress(100, maxProgress);
- WaitRead(flash_mem_base, 64);
- SetProgress(120, maxProgress);
-
- command = string.Format("sunxi_flash phy_read {0:x} {1:x} {2:x};fastboot_test", flash_mem_base, addr / sector_size, size / sector_size);
- ExecCommand(command);
- SetProgress(140, maxProgress);
- var header = WaitRead(flash_mem_base, 64);
- SetProgress(160, maxProgress);
- SetStatus(Resources.Verifying);
- var r = fel.ReadMemory((uint)flash_mem_base, size);
- for (int i = 0; i < size; i++)
+
+ fel.WriteFlash(kernel_base_f, kernel,
+ delegate(Fel.CurrentAction action, string command)
+ {
+ switch (action)
+ {
+ case Fel.CurrentAction.RunningCommand:
+ SetStatus(Resources.ExecutingCommand + " " + command);
+ break;
+ case Fel.CurrentAction.WritingMemory:
+ SetStatus(Resources.UploadingKernel);
+ break;
+ }
+ progress++;
+ SetProgress(progress, maxProgress);
+ }
+ );
+ var r = fel.ReadFlash((UInt32)kernel_base_f, (UInt32)kernel.Length,
+ delegate(Fel.CurrentAction action, string command)
+ {
+ switch (action)
+ {
+ case Fel.CurrentAction.RunningCommand:
+ SetStatus(Resources.ExecutingCommand + " " + command);
+ break;
+ case Fel.CurrentAction.ReadingMemory:
+ SetStatus(Resources.Verifying);
+ break;
+ }
+ progress++;
+ SetProgress(progress, maxProgress);
+ }
+ );
+ for (int i = 0; i < kernel.Length; i++)
if (kernel[i] != r[i])
{
throw new Exception(Resources.VerifyFailed);
}
- if (string.IsNullOrEmpty(Mod))
- ExecCommand(string.Format("boota {0:x}", kernel_base_m), true);
+ var bootCommand = string.Format("boota {0:x}", kernel_base_m);
+ SetStatus(Resources.ExecutingCommand + " " + bootCommand);
+ fel.RunUbootCmd(bootCommand, true);
SetStatus(Resources.Done);
- SetProgress(180, maxProgress);
- Thread.Sleep(1000);
- DialogResult = DialogResult.OK;
-
+ SetProgress(maxProgress, maxProgress);
}
public void Memboot()
{
- const int maxProgress = 75;
- SetProgress(0, maxProgress);
+ int progress = 5;
+ int maxProgress = 300;
+ SetProgress(progress, maxProgress);
byte[] kernel;
if (!string.IsNullOrEmpty(Mod))
@@ -382,29 +351,31 @@ namespace com.clusterrr.hakchi_gui
Array.Copy(kernel, newK, kernel.Length);
kernel = newK;
}
- SetProgress(20, maxProgress);
-
- fel.Open(vid, pid);
- SetStatus(Resources.UploadingFel1);
- fel.WriteMemory((uint)fes1_base_m, Resources.fes1);
- SetProgress(30, maxProgress);
- //Console.WriteLine("OK");
- //var r = fel.ReadMemory(0x2000, (UInt32)fel1.Length);
- SetStatus(Resources.ExecutingFel1);
- fel.Exec((uint)fes1_base_m, 3);
- Thread.Sleep(3000);
- SetProgress(40, maxProgress);
- SetStatus(Resources.UploadingUboot);
- fel.WriteMemory(uboot_base_m, Resources.uboot);
- SetProgress(50, maxProgress);
+
+ progress += 5;
+ maxProgress = kernel.Length / 67000 + 15;
+ SetProgress(progress, maxProgress);
+
SetStatus(Resources.UploadingKernel);
- fel.WriteMemory(flash_mem_base, kernel);
- SetProgress(70, maxProgress);
- ExecCommand(string.Format("boota {0:x}", kernel_base_m), true);
+ fel.WriteMemory(flash_mem_base, kernel,
+ delegate(Fel.CurrentAction action, string command)
+ {
+ switch (action)
+ {
+ case Fel.CurrentAction.WritingMemory:
+ SetStatus(Resources.UploadingKernel);
+ break;
+ }
+ progress++;
+ SetProgress(progress, maxProgress);
+ }
+ );
+
+ var bootCommand = string.Format("boota {0:x}", kernel_base_m);
+ SetStatus(Resources.ExecutingCommand + " " + bootCommand);
+ fel.RunUbootCmd(bootCommand, true);
SetStatus(Resources.Done);
- SetProgress(75, maxProgress);
- Thread.Sleep(1000);
- DialogResult = DialogResult.OK;
+ SetProgress(maxProgress, maxProgress);
}
private byte[] CreatePatchedKernel(string mod, bool createConfig = false, bool originalGames = false, NesGame[] games = null)
diff --git a/hakchi_gui.csproj b/hakchi_gui.csproj
index c9495812..6027cc25 100644
--- a/hakchi_gui.csproj
+++ b/hakchi_gui.csproj
@@ -39,6 +39,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="System.Management" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@@ -106,6 +107,7 @@
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="Settings.cs" />
+ <Compile Include="UnsupportedMapperException.cs" />
<Compile Include="WaitingForm.cs">
<SubType>Form</SubType>
</Compile>