/* 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 path1;
private string path2;
private string path3;
private string path4;
private string image43;
private string image169;
public string Path1 { get { return path1; } set { path1 = value; } }
public string Path2 { get { return path2; } set { path2 = value; } }
public string Path3 { get { return path3; } set { path3 = value; } }
public string Path4 { get { return path4; } set { path4 = value; } }
public string Image43 { get { return image43; } set { image43 = value; } }
public string Image169 { get { return image169; } set { image169 = value; } }
public GXForwarder()
{
}
public GXForwarder(params string[] paths)
{
if (ForwardMii_Plugin.CheckDevKit() == false) throw new Exception("DevkitPro or one of it's components wasn't found!");
path1 = paths[0];
path2 = paths[1];
path3 = paths[2];
path4 = paths[3];
}
public GXForwarder(string Image43, string Image169, params string[] paths)
{
if (ForwardMii_Plugin.CheckDevKit() == false) throw new Exception("DevkitPro or one of it's components wasn't found!");
path1 = paths[0];
path2 = paths[1];
path3 = paths[2];
path4 = paths[3];
image43 = Image43;
image169 = Image169;
}
public void Clear()
{
path1 = string.Empty;
path2 = string.Empty;
path3 = string.Empty;
path4 = string.Empty;
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("---path1---"))
lines[i] = lines[i].Replace("---path1---", path1);
else if (lines[i].Contains("---path2---"))
lines[i] = lines[i].Replace("---path2---", path2);
else if (lines[i].Contains("---path3---"))
lines[i] = lines[i].Replace("---path3---", path3);
else if (lines[i].Contains("---path4---"))
lines[i] = lines[i].Replace("---path4---", path4);
}
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);
}
}
}