Implemented NDS Reading and Exploring

This commit is contained in:
Gericom 2014-11-11 18:56:18 +01:00
parent dcff52d371
commit 9e1f095d4d
8 changed files with 1074 additions and 2 deletions

View File

@ -296,7 +296,7 @@ namespace _3DS
public override FormatMatch IsFormat(EFEFile File)
{
if (File.Data.Length > 20 && File.Data[0] == 'S' && File.Data[1] == 'A' && File.Data[2] == 'R' && File.Data[3] == 'C') return FormatMatch.Content;
if (File.Data.Length > 20 && File.Data[0] == 'S' && File.Data[1] == 'A' && File.Data[2] == 'R' && File.Data[3] == 'C' && File.Data[0x14] == 'S' && File.Data[0x15] == 'F' && File.Data[0x16] == 'A' && File.Data[0x17] == 'T') return FormatMatch.Content;
return FormatMatch.No;
}

View File

@ -1754,7 +1754,12 @@ namespace CommonFiles
public override FormatMatch IsFormat(EFEFile File)
{
String s = Encoding.ASCII.GetString(File.Data);
String s;
try
{
s = Encoding.ASCII.GetString(File.Data);
}
catch { return FormatMatch.No; }
if(s.StartsWith("<?xml") && s.Contains("<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"")) return FormatMatch.Content;
return FormatMatch.No;
}

View File

@ -26,6 +26,7 @@ namespace LibEveryFileExplorer.Files
protected const String Category_Models = "Models";
protected const String Category_Palettes = "Palettes";
protected const String Category_Particles = "Particles";
protected const String Category_Roms = "Roms";
protected const String Category_Screens = "Screens";
protected const String Category_Shaders = "Shaders";
protected const String Category_Strings = "Strings";

383
NDS/NDS.cs Normal file
View File

@ -0,0 +1,383 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using LibEveryFileExplorer.Files;
using System.Drawing;
using System.Windows.Forms;
using LibEveryFileExplorer.Files.SimpleFileSystem;
using NDS.UI;
namespace NDS
{
public class NDS : FileFormat<NDS.NDSIdentifier>, IViewable
{
public NDS(byte[] data)
{
EndianBinaryReader er = new EndianBinaryReader(new MemoryStream(data), Endianness.LittleEndian);
header = new ROM_Header(er);
er.BaseStream.Position = header.main_rom_offset;
main_rom = er.ReadBytes((int)header.main_size);
er.BaseStream.Position = header.sub_rom_offset;
sub_rom = er.ReadBytes((int)header.sub_size);
er.BaseStream.Position = header.fnt_offset;
fnt = new ROM_FNT(er);
er.BaseStream.Position = header.main_ovt_offset;
main_ovt = new ROM_OVT[header.main_ovt_size / 32];
for (int i = 0; i < header.main_ovt_size / 32; i++) main_ovt[i] = new ROM_OVT(er);
er.BaseStream.Position = header.sub_ovt_offset;
sub_ovt = new ROM_OVT[header.sub_ovt_size / 32];
for (int i = 0; i < header.sub_ovt_size / 32; i++) sub_ovt[i] = new ROM_OVT(er);
er.BaseStream.Position = header.fat_offset;
fat = new FileAllocationEntry[header.fat_size / 8];
for (int i = 0; i < header.fat_size / 8; i++) fat[i] = new FileAllocationEntry(er);
er.BaseStream.Position = header.banner_offset;
banner = new BannerFile(er);
FileData = new byte[header.fat_size / 8][];
for (int i = 0; i < header.fat_size / 8; i++)
{
er.BaseStream.Position = fat[i].fileTop;
FileData[i] = er.ReadBytes((int)fat[i].fileSize);
}
er.Close();
}
public Form GetDialog()
{
return new NDSViewer(this);
}
public ROM_Header header;
public class ROM_Header
{
public ROM_Header(EndianBinaryReader er)
{
game_name = er.ReadString(Encoding.ASCII, 12).Replace("\0", "");
game_code = er.ReadString(Encoding.ASCII, 4).Replace("\0", "");
maker_code = er.ReadString(Encoding.ASCII, 2).Replace("\0", "");
product_id = er.ReadByte();
device_type = er.ReadByte();
device_size = er.ReadByte();
reserved_A = er.ReadBytes(9);
game_version = er.ReadByte();
property = er.ReadByte();
main_rom_offset = er.ReadUInt32();
main_entry_address = er.ReadUInt32();
main_ram_address = er.ReadUInt32();
main_size = er.ReadUInt32();
sub_rom_offset = er.ReadUInt32();
sub_entry_address = er.ReadUInt32();
sub_ram_address = er.ReadUInt32();
sub_size = er.ReadUInt32();
fnt_offset = er.ReadUInt32();
fnt_size = er.ReadUInt32();
fat_offset = er.ReadUInt32();
fat_size = er.ReadUInt32();
main_ovt_offset = er.ReadUInt32();
main_ovt_size = er.ReadUInt32();
sub_ovt_offset = er.ReadUInt32();
sub_ovt_size = er.ReadUInt32();
rom_param_A = er.ReadBytes(8);
banner_offset = er.ReadUInt32();
secure_crc = er.ReadUInt16();
rom_param_B = er.ReadBytes(2);
main_autoload_done = er.ReadUInt32();
sub_autoload_done = er.ReadUInt32();
rom_param_C = er.ReadBytes(8);
rom_size = er.ReadUInt32();
header_size = er.ReadUInt32();
reserved_B = er.ReadBytes(0x38);
logo_data = er.ReadBytes(0x9C);
logo_crc = er.ReadUInt16();
header_crc = er.ReadUInt16();
}
public String game_name;//12
public String game_code;//4
public String maker_code;//2
public Byte product_id;
public Byte device_type;
public Byte device_size;
public byte[] reserved_A;//9
public Byte game_version;
public Byte property;
public UInt32 main_rom_offset;
public UInt32 main_entry_address;
public UInt32 main_ram_address;
public UInt32 main_size;
public UInt32 sub_rom_offset;
public UInt32 sub_entry_address;
public UInt32 sub_ram_address;
public UInt32 sub_size;
public UInt32 fnt_offset;
public UInt32 fnt_size;
public UInt32 fat_offset;
public UInt32 fat_size;
public UInt32 main_ovt_offset;
public UInt32 main_ovt_size;
public UInt32 sub_ovt_offset;
public UInt32 sub_ovt_size;
public byte[] rom_param_A;//8
public UInt32 banner_offset;
public UInt16 secure_crc;
public byte[] rom_param_B;//2
public UInt32 main_autoload_done;
public UInt32 sub_autoload_done;
public byte[] rom_param_C;//8
public UInt32 rom_size;
public UInt32 header_size;
public byte[] reserved_B;//0x38
public byte[] logo_data;//0x9C
public UInt16 logo_crc;
public UInt16 header_crc;
}
public Byte[] main_rom;
public Byte[] sub_rom;
public ROM_FNT fnt;
public class ROM_FNT
{
public ROM_FNT(EndianBinaryReader er)
{
directoryTable = new List<DirectoryTableEntry>();
directoryTable.Add(new DirectoryTableEntry(er));
for (int i = 0; i < directoryTable[0].dirParentID - 1; i++)
{
directoryTable.Add(new DirectoryTableEntry(er));
}
entryNameTable = new List<EntryNameTableEntry>();
int dirend = 0;
while (dirend < directoryTable[0].dirParentID)
{
byte entryNameLength = er.ReadByte();
er.BaseStream.Position--;
if (entryNameLength == 0)
{
entryNameTable.Add(new EntryNameTableEndOfDirectoryEntry(er));
dirend++;
}
else if (entryNameLength < 0x80) entryNameTable.Add(new EntryNameTableFileEntry(er));
else entryNameTable.Add(new EntryNameTableDirectoryEntry(er));
}
}
public List<DirectoryTableEntry> directoryTable;
public List<EntryNameTableEntry> entryNameTable;
}
public ROM_OVT[] main_ovt;
public ROM_OVT[] sub_ovt;
public class ROM_OVT
{
[Flags]
public enum OVT_Flag : byte
{
Compressed = 1,
Authentication_Code = 2
}
public ROM_OVT(EndianBinaryReader er)
{
id = er.ReadUInt32();
ram_address = er.ReadUInt32();
ram_size = er.ReadUInt32();
bss_size = er.ReadUInt32();
sinit_init = er.ReadUInt32();
sinit_init_end = er.ReadUInt32();
file_id = er.ReadUInt32();
UInt32 tmp = er.ReadUInt32();
compressed = tmp & 0xFFFFFF;
flag = (OVT_Flag)(tmp >> 24);
}
public UInt32 id;
public UInt32 ram_address;
public UInt32 ram_size;
public UInt32 bss_size;
public UInt32 sinit_init;
public UInt32 sinit_init_end;
public UInt32 file_id;
public UInt32 compressed;//:24;
public OVT_Flag flag;// :8;
}
public FileAllocationEntry[] fat;
public BannerFile banner;
public class BannerFile
{
public BannerFile(EndianBinaryReader er)
{
h = new BannerHeader(er);
v1 = new BannerFileV1(er);
}
BannerHeader h;
public class BannerHeader
{
public BannerHeader(EndianBinaryReader er)
{
version = er.ReadByte();
reserved_A = er.ReadByte();
crc16_v1 = er.ReadUInt16();
reserved_B = er.ReadBytes(28);
}
public Byte version;
public Byte reserved_A;
public UInt16 crc16_v1;
public Byte[] reserved_B;//28
}
BannerFileV1 v1;
public class BannerFileV1
{
public BannerFileV1(EndianBinaryReader er)
{
image = er.ReadBytes(32 * 32 / 2);
pltt = er.ReadBytes(16 * 2);
gameName = new string[6];
gameName[0] = er.ReadString(Encoding.Unicode, 128).Replace("\0", "");
gameName[1] = er.ReadString(Encoding.Unicode, 128).Replace("\0", "");
gameName[2] = er.ReadString(Encoding.Unicode, 128).Replace("\0", "");
gameName[3] = er.ReadString(Encoding.Unicode, 128).Replace("\0", "");
gameName[4] = er.ReadString(Encoding.Unicode, 128).Replace("\0", "");
gameName[5] = er.ReadString(Encoding.Unicode, 128).Replace("\0", "");
}
public Byte[] image;//32*32/2
public Byte[] pltt;//16*2
public String[] gameName;//6, 128 chars (UTF16-LE)
}
}
public Byte[][] FileData;
public SFSDirectory ToFileSystem()
{
bool treereconstruct = false;//Some programs do not write the Directory Table well, so sometimes I need to reconstruct the tree based on the fnt, which is bad!
List<SFSDirectory> dirs = new List<SFSDirectory>();
dirs.Add(new SFSDirectory("/", true));
dirs[0].DirectoryID = 0xF000;
uint nrdirs = fnt.directoryTable[0].dirParentID;
for (int i = 1; i < nrdirs; i++)
{
dirs.Add(new SFSDirectory((ushort)(0xF000 + i)));
}
for (int i = 1; i < nrdirs; i++)
{
if (fnt.directoryTable[i].dirParentID - 0xF000 == i)
{
treereconstruct = true;
foreach (var v in dirs)
{
v.Parent = null;
}
break;
}
dirs[i].Parent = dirs[fnt.directoryTable[i].dirParentID - 0xF000];
}
if (!treereconstruct)
{
for (int i = 0; i < nrdirs; i++)
{
for (int j = 0; j < nrdirs; j++)
{
if (dirs[i] == dirs[j].Parent)
{
dirs[i].SubDirectories.Add(dirs[j]);
}
}
}
}
uint offset = nrdirs * 8;
ushort fileid = fnt.directoryTable[0].dirEntryFileID;
SFSDirectory curdir = null;
foreach (EntryNameTableEntry e in fnt.entryNameTable)
{
for (int i = 0; i < nrdirs; i++)
{
if (offset == fnt.directoryTable[i].dirEntryStart)
{
curdir = dirs[i];
break;
}
}
if (e is EntryNameTableEndOfDirectoryEntry)
{
curdir = null;
offset++;
}
else if (e is EntryNameTableFileEntry)
{
curdir.Files.Add(new SFSFile(fileid++, ((EntryNameTableFileEntry)e).entryName, curdir));
offset += 1u + e.entryNameLength;
}
else if (e is EntryNameTableDirectoryEntry)
{
if (treereconstruct)
{
dirs[((EntryNameTableDirectoryEntry)e).directoryID - 0xF000].Parent = curdir;
curdir.SubDirectories.Add(dirs[((EntryNameTableDirectoryEntry)e).directoryID - 0xF000]);
}
dirs[((EntryNameTableDirectoryEntry)e).directoryID - 0xF000].DirectoryName = ((EntryNameTableDirectoryEntry)e).entryName;
offset += 3u + (e.entryNameLength & 0x7Fu);
}
}
for (int i = (int)(header.main_ovt_size / 32 + header.sub_ovt_size / 32); i < header.fat_size / 8; i++)
{
//byte[] data = new byte[fat[i].fileSize];
//Array.Copy(FileData FIMG.fileImage, fat[i].fileTop, data, 0, data.Length);
dirs[0].GetFileByID((ushort)i).Data = FileData[i];//data;
}
return dirs[0];
}
public class NDSIdentifier : FileFormatIdentifier
{
public override string GetCategory()
{
return Category_Roms;
}
public override string GetFileDescription()
{
return "Nintendo DS Rom (NDS)";
}
public override string GetFileFilter()
{
return "Nintendo DS Rom (*.nds, *.srl)|*.nds;*.srl";
}
public override Bitmap GetIcon()
{
return null;
}
public override FormatMatch IsFormat(EFEFile File)
{
if (File.Name.ToLower().EndsWith(".nds") || File.Name.ToLower().EndsWith(".srl")) return FormatMatch.Extension;
return FormatMatch.No;
}
}
}
}

View File

@ -54,6 +54,7 @@
<ItemGroup>
<Compile Include="GPU\CommandContext.cs" />
<Compile Include="GPU\Textures.cs" />
<Compile Include="NDS.cs" />
<Compile Include="NitroSystem\FND\NARC.cs" />
<Compile Include="NitroFS.cs" />
<Compile Include="NitroSystem\G3D\Dictionary.cs" />
@ -71,6 +72,12 @@
<DependentUpon>Resource.resx</DependentUpon>
</Compile>
<Compile Include="SND\ADPCM.cs" />
<Compile Include="UI\NDSViewer.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\NDSViewer.Designer.cs">
<DependentUpon>NDSViewer.cs</DependentUpon>
</Compile>
<Compile Include="UI\MDL0MaterialEditor.cs">
<SubType>UserControl</SubType>
</Compile>
@ -119,6 +126,9 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="UI\NDSViewer.resx">
<DependentUpon>NDSViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\MDL0MaterialEditor.resx">
<DependentUpon>MDL0MaterialEditor.cs</DependentUpon>
</EmbeddedResource>

277
NDS/UI/NDSViewer.Designer.cs generated Normal file
View File

@ -0,0 +1,277 @@
namespace NDS.UI
{
partial class NDSViewer
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NDSViewer));
this.fileBrowser1 = new LibEveryFileExplorer.UI.FileBrowser();
this.mainMenu1 = new LibEveryFileExplorer.UI.MainMenu(this.components);
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.menuItem4 = new System.Windows.Forms.MenuItem();
this.menuExport = new System.Windows.Forms.MenuItem();
this.menuItem13 = new System.Windows.Forms.MenuItem();
this.menuReplace = new System.Windows.Forms.MenuItem();
this.menuRename = new System.Windows.Forms.MenuItem();
this.menuDelete = new System.Windows.Forms.MenuItem();
this.menuItem5 = new System.Windows.Forms.MenuItem();
this.menuItem6 = new System.Windows.Forms.MenuItem();
this.menuItem7 = new System.Windows.Forms.MenuItem();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.menuItem8 = new System.Windows.Forms.MenuItem();
this.menuItem9 = new System.Windows.Forms.MenuItem();
this.menuItem14 = new System.Windows.Forms.MenuItem();
this.menuItem10 = new System.Windows.Forms.MenuItem();
this.menuItem11 = new System.Windows.Forms.MenuItem();
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
this.SuspendLayout();
//
// fileBrowser1
//
this.fileBrowser1.DeleteEnabled = false;
this.fileBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
this.fileBrowser1.Location = new System.Drawing.Point(0, 0);
this.fileBrowser1.Name = "fileBrowser1";
this.fileBrowser1.RenameEnabled = false;
this.fileBrowser1.ShowAddDirectoryButton = false;
this.fileBrowser1.ShowAddFileButton = false;
this.fileBrowser1.ShowDeleteButton = false;
this.fileBrowser1.ShowRenameButton = false;
this.fileBrowser1.Size = new System.Drawing.Size(652, 338);
this.fileBrowser1.TabIndex = 0;
this.fileBrowser1.OnDirectoryChanged += new LibEveryFileExplorer.UI.FileBrowser.OnDirectoryChangedEventHandler(this.fileBrowser1_OnDirectoryChanged);
this.fileBrowser1.OnFileActivated += new LibEveryFileExplorer.UI.FileBrowser.OnFileActivatedEventHandler(this.fileBrowser1_OnFileActivated);
this.fileBrowser1.OnAddDirectory += new System.EventHandler(this.fileBrowser1_OnAddDirectory);
this.fileBrowser1.OnAddFile += new System.EventHandler(this.fileBrowser1_OnAddFile);
this.fileBrowser1.OnRemove += new System.EventHandler(this.fileBrowser1_OnRemove);
this.fileBrowser1.OnRename += new System.EventHandler(this.fileBrowser1_OnRename);
this.fileBrowser1.OnSelectionChanged += new System.EventHandler(this.fileBrowser1_OnSelectionChanged);
this.fileBrowser1.OnRightClick += new LibEveryFileExplorer.UI.FileBrowser.OnRightClickEventHandler(this.fileBrowser1_OnRightClick);
//
// mainMenu1
//
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.menuItem5});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem2,
this.menuItem3,
this.menuItem4,
this.menuExport,
this.menuItem13,
this.menuReplace,
this.menuRename,
this.menuDelete});
this.menuItem1.MergeOrder = 1;
this.menuItem1.MergeType = System.Windows.Forms.MenuMerge.MergeItems;
this.menuItem1.Text = "Edit";
//
// menuItem2
//
this.menuItem2.Index = 0;
this.menuItem2.Text = "Add Folder...";
this.menuItem2.Visible = false;
this.menuItem2.Click += new System.EventHandler(this.fileBrowser1_OnAddDirectory);
//
// menuItem3
//
this.menuItem3.Index = 1;
this.menuItem3.Text = "Add File...";
this.menuItem3.Visible = false;
this.menuItem3.Click += new System.EventHandler(this.fileBrowser1_OnAddFile);
//
// menuItem4
//
this.menuItem4.Index = 2;
this.menuItem4.Text = "-";
this.menuItem4.Visible = false;
//
// menuExport
//
this.menuExport.Enabled = false;
this.menuExport.Index = 3;
this.menuExport.Text = "Export...";
this.menuExport.Click += new System.EventHandler(this.menuExport_Click);
//
// menuItem13
//
this.menuItem13.Index = 4;
this.menuItem13.Text = "-";
this.menuItem13.Visible = false;
//
// menuReplace
//
this.menuReplace.Enabled = false;
this.menuReplace.Index = 5;
this.menuReplace.Text = "Replace...";
this.menuReplace.Visible = false;
this.menuReplace.Click += new System.EventHandler(this.menuReplace_Click);
//
// menuRename
//
this.menuRename.Enabled = false;
this.menuRename.Index = 6;
this.menuRename.Text = "Rename...";
this.menuRename.Visible = false;
this.menuRename.Click += new System.EventHandler(this.fileBrowser1_OnRename);
//
// menuDelete
//
this.menuDelete.Enabled = false;
this.menuDelete.Index = 7;
this.menuDelete.Text = "Delete";
this.menuDelete.Visible = false;
this.menuDelete.Click += new System.EventHandler(this.fileBrowser1_OnRemove);
//
// menuItem5
//
this.menuItem5.Index = 1;
this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem6,
this.menuItem7});
this.menuItem5.MergeOrder = 3;
this.menuItem5.MergeType = System.Windows.Forms.MenuMerge.MergeItems;
this.menuItem5.Text = "Tools";
//
// menuItem6
//
this.menuItem6.Index = 0;
this.menuItem6.Text = "-";
//
// menuItem7
//
this.menuItem7.Index = 1;
this.menuItem7.Text = "Export Directory Content...";
this.menuItem7.Click += new System.EventHandler(this.menuItem7_Click);
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
this.openFileDialog1.Filter = "All Files (*.*)|*.*";
this.openFileDialog1.Title = "Import File";
//
// folderBrowserDialog1
//
this.folderBrowserDialog1.Description = "Select the directory to export the content of current directory to.";
//
// contextMenu1
//
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem8,
this.menuItem9,
this.menuItem14,
this.menuItem10,
this.menuItem11});
//
// menuItem8
//
this.menuItem8.Index = 0;
this.menuItem8.Text = "Export...";
this.menuItem8.Click += new System.EventHandler(this.menuExport_Click);
//
// menuItem9
//
this.menuItem9.Index = 1;
this.menuItem9.Text = "-";
this.menuItem9.Visible = false;
//
// menuItem14
//
this.menuItem14.Index = 2;
this.menuItem14.Text = "Replace...";
this.menuItem14.Visible = false;
this.menuItem14.Click += new System.EventHandler(this.menuReplace_Click);
//
// menuItem10
//
this.menuItem10.Index = 3;
this.menuItem10.Text = "Rename...";
this.menuItem10.Visible = false;
this.menuItem10.Click += new System.EventHandler(this.fileBrowser1_OnRename);
//
// menuItem11
//
this.menuItem11.Index = 4;
this.menuItem11.Text = "Delete";
this.menuItem11.Visible = false;
this.menuItem11.Click += new System.EventHandler(this.fileBrowser1_OnRemove);
//
// saveFileDialog1
//
this.saveFileDialog1.Title = "Export...";
//
// NDSViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(652, 338);
this.Controls.Add(this.fileBrowser1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Menu = this.mainMenu1;
this.Name = "NDSViewer";
this.Text = "NARC Viewer";
this.Load += new System.EventHandler(this.NARCViewer_Load);
this.ResumeLayout(false);
}
#endregion
private LibEveryFileExplorer.UI.FileBrowser fileBrowser1;
private LibEveryFileExplorer.UI.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.MenuItem menuRename;
private System.Windows.Forms.MenuItem menuDelete;
private System.Windows.Forms.MenuItem menuItem5;
private System.Windows.Forms.MenuItem menuItem6;
private System.Windows.Forms.MenuItem menuItem7;
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.MenuItem menuItem8;
private System.Windows.Forms.MenuItem menuItem9;
private System.Windows.Forms.MenuItem menuItem10;
private System.Windows.Forms.MenuItem menuItem11;
private System.Windows.Forms.MenuItem menuExport;
private System.Windows.Forms.MenuItem menuItem13;
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
private System.Windows.Forms.MenuItem menuReplace;
private System.Windows.Forms.MenuItem menuItem14;
}
}

236
NDS/UI/NDSViewer.cs Normal file
View File

@ -0,0 +1,236 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LibEveryFileExplorer.Files.SimpleFileSystem;
using LibEveryFileExplorer;
using LibEveryFileExplorer.Files;
using NDS.NitroSystem.FND;
namespace NDS.UI
{
public partial class NDSViewer : Form, IChildReactive
{
NDS Archive;
SFSDirectory Root;
public NDSViewer(NDS Archive)
{
this.Archive = Archive;
Root = Archive.ToFileSystem();
InitializeComponent();
}
private void NARCViewer_Load(object sender, EventArgs e)
{
fileBrowser1.UpdateDirectories(Root.GetTreeNodes());
}
private void fileBrowser1_OnDirectoryChanged(string Path)
{
var d = Root.GetDirectoryByPath(Path);
fileBrowser1.UpdateContent(d.GetContent());
}
private void fileBrowser1_OnFileActivated(string Path)
{
var s = Root.GetFileByPath(Path);
EveryFileExplorerUtil.OpenFile(new EFESFSFile(s), ((ViewableFile)Tag).File);
}
private void fileBrowser1_OnAddDirectory(object sender, EventArgs e)
{
/*var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedFolderPath);
if (dir == null) return;
String name = null;
retry:
name = Microsoft.VisualBasic.Interaction.InputBox("Please give the name of the new directory:", "New Directory", name);
if (name == null || name.Length == 0) return;
if (dir.IsValidName(name))
{
SFSDirectory d = new SFSDirectory(name, false);
d.Parent = dir;
dir.SubDirectories.Add(d);
Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true);
}
else
{
MessageBox.Show("The name contains either one or more invalid chars, or is already in use!", "Invalid Name");
goto retry;
}*/
}
private void fileBrowser1_OnAddFile(object sender, EventArgs e)
{
/*if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
&& openFileDialog1.FileName.Length > 0)
{
var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedFolderPath);
if (!dir.IsValidName(System.IO.Path.GetFileName(openFileDialog1.FileName)))
{
switch (MessageBox.Show("A file with the same name as the selected file exists. Do you want to replace this file?", "Replace", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
{
case System.Windows.Forms.DialogResult.Yes:
var file = Root.GetFileByPath(fileBrowser1.SelectedFolderPath + "/" + System.IO.Path.GetFileName(openFileDialog1.FileName));
file.Data = System.IO.File.ReadAllBytes(openFileDialog1.FileName);
break;
case System.Windows.Forms.DialogResult.No:
int nr = 0;
String NewName;
do
{
NewName = System.IO.Path.GetFileNameWithoutExtension(openFileDialog1.FileName) + "_" + nr++ + System.IO.Path.GetExtension(openFileDialog1.FileName);
}
while (!dir.IsValidName(NewName));
SFSFile f = new SFSFile(-1, NewName, dir);
f.Data = System.IO.File.ReadAllBytes(openFileDialog1.FileName);
dir.Files.Add(f);
break;
}
}
else
{
SFSFile f = new SFSFile(-1, System.IO.Path.GetFileName(openFileDialog1.FileName), dir);
f.Data = System.IO.File.ReadAllBytes(openFileDialog1.FileName);
dir.Files.Add(f);
}
Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true);
}*/
}
private void fileBrowser1_OnRemove(object sender, EventArgs e)
{
/*if (fileBrowser1.SelectedFolderPath == fileBrowser1.SelectedPath) return;
var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedPath);
if (dir != null)
{
if (MessageBox.Show("Are you sure you permanently want to delete this directory: " + dir.DirectoryName + ", and all of it's files and subfolders?", "Removal", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.No) return;
dir.Parent.SubDirectories.Remove(dir);
Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true);
}
else
{
var file = Root.GetFileByPath(fileBrowser1.SelectedPath);
if (MessageBox.Show("Are you sure you permanently want to delete this file: " + file.FileName + "?", "Removal", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.No) return;
file.Parent.Files.Remove(file);
Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true);
}*/
}
private void fileBrowser1_OnRename(object sender, EventArgs e)
{
/*if (fileBrowser1.SelectedFolderPath == fileBrowser1.SelectedPath) return;
var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedPath);
if (dir != null)
{
String name = dir.DirectoryName;
retryd:
name = Microsoft.VisualBasic.Interaction.InputBox("Please give the new name for this directory:", "Rename", name);
if (name == null || name.Length == 0) return;
if (dir.Parent.IsValidName(name))
{
String oldpath = dir.ToString();
dir.DirectoryName = name;
String newpath = dir.ToString();
Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true, oldpath.Remove(oldpath.Length - 1), newpath.Remove(newpath.Length - 1));
}
else
{
MessageBox.Show("The name contains either one or more invalid chars, or is already in use!", "Invalid Name");
goto retryd;
}
}
else//file
{
var file = Root.GetFileByPath(fileBrowser1.SelectedPath);
String name = file.FileName;
retryf:
name = Microsoft.VisualBasic.Interaction.InputBox("Please give the new name for this file:", "Rename", name);
if (name == null || name.Length == 0) return;
if (file.Parent.IsValidName(name))
{
file.FileName = name;
Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true);
}
else
{
MessageBox.Show("The name contains either one or more invalid chars, or is already in use!", "Invalid Name");
goto retryf;
}
}*/
}
private void fileBrowser1_OnSelectionChanged(object sender, EventArgs e)
{
fileBrowser1.RenameEnabled = fileBrowser1.DeleteEnabled = menuRename.Enabled = menuDelete.Enabled = !(fileBrowser1.SelectedPath == fileBrowser1.SelectedFolderPath);
if (Root.GetDirectoryByPath(fileBrowser1.SelectedPath) == null) menuExport.Enabled = menuReplace.Enabled = true;
else menuExport.Enabled = menuReplace.Enabled = false;
}
private void menuItem7_Click(object sender, EventArgs e)
{
var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedFolderPath);
if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
&& folderBrowserDialog1.SelectedPath.Length > 0)
{
dir.Export(folderBrowserDialog1.SelectedPath);
}
}
private void fileBrowser1_OnRightClick(Point Location)
{
var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedPath);
if (dir != null)
{
}
else
{
//var file = Root.GetFileByPath(fileBrowser1.SelectedPath);
contextMenu1.Show(fileBrowser1, Location);
}
}
private void menuExport_Click(object sender, EventArgs e)
{
var file = Root.GetFileByPath(fileBrowser1.SelectedPath);
if (file == null) return;
saveFileDialog1.Filter = System.IO.Path.GetExtension(fileBrowser1.SelectedPath).Replace(".", "").ToUpper() + " Files (*" + System.IO.Path.GetExtension(fileBrowser1.SelectedPath).ToLower() + ")|*" + System.IO.Path.GetExtension(fileBrowser1.SelectedPath).ToLower() + "|All Files (*.*)|*.*";
saveFileDialog1.FileName = System.IO.Path.GetFileName(fileBrowser1.SelectedPath);
if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
&& saveFileDialog1.FileName.Length > 0)
{
System.IO.File.Create(saveFileDialog1.FileName).Close();
System.IO.File.WriteAllBytes(saveFileDialog1.FileName, file.Data);
}
}
private void menuReplace_Click(object sender, EventArgs e)
{
/*if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
&& openFileDialog1.FileName.Length > 0)
{
var file = Root.GetFileByPath(fileBrowser1.SelectedPath);
file.Data = System.IO.File.ReadAllBytes(openFileDialog1.FileName);
Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true);
}*/
}
public void OnChildSave(ViewableFile File)
{
/*Archive.FromFileSystem(Root);
fileBrowser1.UpdateDirectories(Root.GetTreeNodes(), true);
*/
}
}
}

160
NDS/UI/NDSViewer.resx Normal file
View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>134, 17</value>
</metadata>
<metadata name="folderBrowserDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>274, 17</value>
</metadata>
<metadata name="contextMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>443, 17</value>
</metadata>
<metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>573, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAADwAAABcAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAA
ABoAAAAXAAAADwAAAB4BM2aeAUSHxQFEh8UBRIfFAUSHxQFEh8UBRIfFAUSHxQFEh8UBRIfFAUSHxQFE
h8UBRIfFATNmngAAAB4AAAAAAUqUuHuu4P96rd//eq3f/3qt3/96rd//eq3f/3qt3/96rd//eq3f/3qt
3/96rd//e67g/wFKlLgAAAAAAAAAAAJRoKuBtOT/fbDh/32w4f99sOH/fbDh/2yf0P9ajb//Wo2//1qN
v/9ajb//Wo2//3Cj0/8CUaCrAAAAAAAAAAACVKSmiLvq/4K15f+CteX/grXl/4K15f9jlsf/4uLR/+Li
0f/i4tH/4uLR/+Li0f9pnMv/AlSkpgAAAAAAAAAAA1aoo4/C7v+Huun/h7rp/4e66f+Huun/cKPT/+zs
2/+6uqn/0NC//83NvP/s7Nv/eKvY/wNWqKMAAAAAAAAAAANYrJ+WyfL/jL/s/4y/7P+Mv+z/RHeq/0J1
qP/19eT/9fXk//X15P/19eT/9fXk/4i75f8DWKyfAAAAAAAAAAADWrCbm872/5HE8P+RxPD/kcTw/1WI
u/9Uh7r//8tD//zFPf/4vTX/87Ut//CuJv+WyfL/A1qwmwAAAAAAAAAAA1uzmJ/S+f+VyPP/lcjz/5XI
8/9ViLv/VYi7/1WIu/9NgLP/lcjz/5XI8/+VyPP/n9L5/wNbs5gAAAAAAAAAAANdtpWn2/79qt3//6rd
//+q3f//d6rd/3eq3f93qt3/ZpnM/6rd//+q3f//qt3//6fb/v0DXbaVAAAAAAAAAAAEX7lta6bf4ICz
5v+As+b/gLPm/06BtP9OgbT/ToG0/0h7rv+As+b/gLPm/4Cz5v9rpt/gBF+5bQAAAAAAAAAABGC8R02U
2cSJvO//iLvu/4i77v9BdKf/QXSn/0F0p/8+caT/iLvu/4i77v+JvO//TZTZxARgvEcAAAAAAAAAAARh
viMqfMylibzv/4i77v+Iu+7/NWib/zVom/81aJv/NWib/4i77v+Iu+7/ibzv/yp8zKUEYb4jAAAAAAAA
AAAEYr8EBGLAaARiwIsEYsCLBGLAiwBAgMwAQIDMAECAzABAgMwEYsCLBGLAiwRiwIsEYsBoBGK/BAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA//8AAAAAAAAAAAAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
AACAAQAA//8AAA==
</value>
</data>
</root>