/* This file is part of CustomizeMii
* Copyright (C) 2009 Leathl
*
* CustomizeMii is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CustomizeMii is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Runtime.InteropServices;
namespace ForwardMii
{
public class GXForwarder
{
private readonly string TempDir = Path.GetTempPath() + "ForwardMii_Temp\\" + Guid.NewGuid() + "\\";
private string thisAppFolder;
private bool elfFirst = false;
private bool usbFirst = false;
private string image43;
private string image169;
public string AppFolder { get { return thisAppFolder; } set { thisAppFolder = value; } }
public bool ElfFirst { get { return elfFirst; } set { elfFirst = value; } }
public bool UsbFirst { get { return usbFirst; } set { usbFirst = value; } }
public string Image43 { get { return image43; } set { image43 = value; } }
public string Image169 { get { return image169; } set { image169 = value; } }
public GXForwarder()
{
}
public GXForwarder(string AppFolder)
{
if (ForwardMii_Plugin.CheckDevKit() == false) throw new Exception("DevkitPro or one of it's components wasn't found!");
thisAppFolder = AppFolder;
}
public GXForwarder(string AppFolder, bool UsbFirst)
{
if (ForwardMii_Plugin.CheckDevKit() == false) throw new Exception("DevkitPro or one of it's components wasn't found!");
thisAppFolder = AppFolder;
usbFirst = UsbFirst;
}
public GXForwarder(string AppFolder, string Image43, string Image169)
{
if (ForwardMii_Plugin.CheckDevKit() == false) throw new Exception("DevkitPro or one of it's components wasn't found!");
thisAppFolder = AppFolder;
image43 = Image43;
image169 = Image169;
}
public GXForwarder(string AppFolder, bool UsbFirst, bool ElfFirst)
{
if (ForwardMii_Plugin.CheckDevKit() == false) throw new Exception("DevkitPro or one of it's components wasn't found!");
thisAppFolder = AppFolder;
usbFirst = UsbFirst;
elfFirst = ElfFirst;
}
public GXForwarder(string AppFolder, bool UsbFirst, bool ElfFirst, string Image43, string Image169)
{
if (ForwardMii_Plugin.CheckDevKit() == false) throw new Exception("DevkitPro or one of it's components wasn't found!");
thisAppFolder = AppFolder;
image43 = Image43;
image169 = Image169;
usbFirst = UsbFirst;
elfFirst = ElfFirst;
}
public void Clear()
{
thisAppFolder = string.Empty;
elfFirst = false;
usbFirst = false;
image43 = string.Empty;
image169 = string.Empty;
}
public void Save(string Destionation)
{
Save(Destionation, false);
}
public void Save(string Destination, bool Overwrite)
{
byte[] theForwarder = ToByteArray();
if (Path.HasExtension(Destination) == false) Destination += ".dol";
if (File.Exists(Destination))
{
if (Overwrite == true)
File.Delete(Destination);
else
throw new Exception("The destination file already exists!");
}
using (FileStream fs = new FileStream(Destination, FileMode.Create))
{
fs.Write(theForwarder, 0, theForwarder.Length);
}
}
public byte[] ToByteArray()
{
MemoryStream ms = this.ToMemoryStream();
return ms.ToArray();
}
public MemoryStream ToMemoryStream()
{
try
{
if (Directory.Exists(TempDir)) Directory.Delete(TempDir, true);
CopyResources();
EditMainCpp();
CopyImages();
if (Compile() == false) throw new Exception("An error occured during compiling!");
byte[] fileTemp = File.ReadAllBytes(TempDir + "boot.dol");
try { Directory.Delete(TempDir, true); }
catch { }
return new MemoryStream(fileTemp);
}
catch (Exception ex)
{
if (Directory.Exists(TempDir)) Directory.Delete(TempDir, true);
throw new Exception(ex.Message);
}
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint GetShortPathName([MarshalAs(UnmanagedType.LPTStr)] string lpszLongPath,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszShortPath, uint cchBuffer);
public static string GetShortPathName(string longPath)
{
uint size = 256;
StringBuilder buffer = new StringBuilder((int)size);
uint result = GetShortPathName(longPath, buffer, size);
return buffer.ToString();
}
private bool Compile()
{
try
{
string tempDir = TempDir;
if (tempDir.Contains(" ")) { tempDir = GetShortPathName(tempDir); }
ProcessStartInfo makeI = new ProcessStartInfo("make", "-C " + tempDir);
makeI.UseShellExecute = false;
makeI.CreateNoWindow = true;
Process make = Process.Start(makeI);
make.WaitForExit();
make.Close();
if (File.Exists(TempDir + "boot.dol") && File.Exists(TempDir + "boot.elf"))
{
return true;
}
else return false;
}
catch { return false; }
}
private void CopyImages()
{
if (!string.IsNullOrEmpty(image43) && File.Exists(image43))
{
try
{
Image img = Image.FromFile(image43);
if (img.Width != 640 || img.Height != 480)
img = ResizeImage(img, 640, 480);
img.Save(TempDir + "\\source\\images\\background.png", System.Drawing.Imaging.ImageFormat.Png);
}
catch
{
Bitmap img = new Bitmap(640, 480);
img.Save(TempDir + "\\source\\images\\background.png", System.Drawing.Imaging.ImageFormat.Png);
}
}
else
{
Bitmap img = new Bitmap(640, 480);
img.Save(TempDir + "\\source\\images\\background.png", System.Drawing.Imaging.ImageFormat.Png);
}
if (!string.IsNullOrEmpty(image169) && File.Exists(image169))
{
try
{
Image img = Image.FromFile(image169);
if (img.Width != 640 || img.Height != 480)
img = ResizeImage(img, 640, 480);
img.Save(TempDir + "\\source\\images\\background169.png", System.Drawing.Imaging.ImageFormat.Png);
}
catch
{
Bitmap img = new Bitmap(640, 480);
img.Save(TempDir + "\\source\\images\\background169.png", System.Drawing.Imaging.ImageFormat.Png);
}
}
else
{
Bitmap img = new Bitmap(640, 480);
img.Save(TempDir + "\\source\\images\\background169.png", System.Drawing.Imaging.ImageFormat.Png);
}
}
private Image ResizeImage(Image img, int x, int y)
{
Image newimage = new Bitmap(x, y);
using (Graphics gfx = Graphics.FromImage(newimage))
{
gfx.DrawImage(img, 0, 0, x, y);
}
return newimage;
}
private void EditMainCpp()
{
Stream maincpp = GetReourceStream("main.cpp");
StreamReader reader = new StreamReader(maincpp);
List tempLines = new List();
string tempLine;
while ((tempLine = reader.ReadLine()) != null)
{
tempLines.Add(tempLine);
}
string[] lines = tempLines.ToArray();
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].Contains("appfolder"))
lines[i] = lines[i].Replace("appfolder", thisAppFolder);
else if (lines[i].Contains("#define USB_FIRST"))
lines[i] = lines[i].Replace("false", usbFirst.ToString().ToLower());
else if (lines[i].Contains("#define ELF_FIRST"))
lines[i] = lines[i].Replace("false", elfFirst.ToString().ToLower());
}
using (FileStream fs = new FileStream(TempDir + "source\\main.cpp", FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(fs))
{
foreach (string thisLine in lines)
{
writer.WriteLine(thisLine);
}
}
}
}
private void CopyResources()
{
if (Directory.Exists(TempDir)) Directory.Delete(TempDir, true);
Directory.CreateDirectory(TempDir + "source\\images");
string[] Resources = new string[] { "dolloader.c", "dolloader.h", "elf_abi.h", "elfloader.c",
"elfloader.h", "fatmounter.c", "fatmounter.h", "filelist.h", "video.cpp", "video.h" };
foreach (string thisResource in Resources)
{
Stream tempStream = GetReourceStream(thisResource);
StreamToFile(tempStream, TempDir + "source\\" + thisResource);
}
Stream makefile = GetReourceStream("Makefile");
StreamToFile(makefile, TempDir + "Makefile");
}
private void StreamToFile(Stream theStream, string Destination)
{
using (FileStream fs = new FileStream(Destination, FileMode.Create))
{
byte[] temp = new byte[theStream.Length];
theStream.Read(temp, 0, temp.Length);
fs.Write(temp, 0, temp.Length);
//int count = 0;
//int length = 4096;
//byte[] buffer = new byte[length];
//while ((count = theStream.Read(buffer, 0, length)) != 0)
// fs.Write(buffer, 0, length);
}
}
private MemoryStream GetReourceStream(string theResource)
{
Stream thisStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ForwardMii.Resources.GX." + theResource);
byte[] thisArray = new byte[thisStream.Length];
thisStream.Read(thisArray, 0, thisArray.Length);
return new MemoryStream(thisArray);
}
}
}