Getting started guide
Welcome to Ekona, a library part of the SceneGate framework that provides support for DS and DSi file formats.
Usage
The project provides the following .NET libraries (NuGet packages in nuget.org). The libraries works on supported versions of .NET: 6.0 and 8.0.
-
SceneGate.Ekona.Containers.Rom
: DS and DSi cartridge (ROM) format.SceneGate.Ekona.Security
: hash and encryption algorithms
Quick start
Cartridge file system
Let's start by opening a game (ROM) and accessing to its files. We can virtually
unpack the ROM by using the converter
Binar2NitroRom
. It will
create a tree of nodes that we can use to access to the files.
// Create node from file with binary format.
Node game = NodeFactory.FromFile(gameFilePath, FileOpenMode.Read);
// Use the `Binary2NitroRom` converter to convert the binary format
// into node containers (virtual file system tree).
game.TransformWith<Binary2NitroRom>();
// And it's done!
// Now we can access to every game file. For instance, we can export one file
Node gameFile = game.Children["data"].Children["Items.dat"];
gameFile.Stream.WriteTo("dump/items.dat");
Note
The converter will not write any file to the disk. It will create a tree of
nodes that points to different parts of the original game file. If it needs to
decrypt a file (like arm9i
), it will create a new stream on memory.
Now we can quickly modify our file even by code!
// Read the file by converting from binary format into PO (translation format)
Node itemsFile = Navigator.SearchNode(game, "data/Items.dat");
Po items = itemsFile.TransformWith<BinaryItems2Po>().GetFormatAs<Po>();
// Let's modify the first entry
items.Entries[0].Translated = "Hello world!";
// Convert back from PO format into binary (write into a new memory stream)
itemsFile.TransformWith<Po2BinaryItems>();
Finally, to generate a new game (ROM) file we just need one more line of code to
use the NitroRom2Binary
converter.
game.TransformWith<NitroRom2Binary>();
game.Stream.WriteTo("output/new_game.nds");
Tip
Check-out the cartridge section to learn about the optional parameters of these converters!
Cartridge information
Once we have opened a game, we can access to all the information from its header
easily via the system/info
node.
Node game = NodeFactory.FromFile(gameFilePath, FileOpenMode.Read)
.TransformWith<Binary2NitroRom>();
ProgramInfo info = game.Children["system"].Children["info"]
.GetFormatAs<ProgramInfo>();
Console.WriteLine($"Game title: {info.GameTitle} [{info.GameCode}]");
In a similar way, you can access to the information from the banner like the game title in different languages:
Banner bannerInfo = Navigator.SearchNode(game, "system/banner/info").GetFormatAs<Banner>();
Console.WriteLine($"Japanese title: {bannerInfo.JapaneseTitle}");
Console.WriteLine($"English title: {bannerInfo.EnglishTitle}");
You can also export the game icon. If it's a DSi game, it may even have an animated icon that you can export as GIF!
IndexedPaletteImage icon = Navigator.SearchNode(game, "system/banner/icon")
.GetFormatAs<IndexedPaletteImage>();
// Using Texim converters, create a PNG image
var converterParameters = new IndexedImageBitmapParams { Palettes = icon };
var bitmapConverter = new IndexedImage2Bitmap(converterParameters);
using BinaryFormat binaryPng = bitmapConverter.Convert(icon);
binaryPng.Stream.WriteTo("dump/icon.png");
// For DSi-enhanced games we can export its animated icon as GIF
if (bannerInfo.SupportAnimatedIcon) {
var animatedNode = Navigator.SearchNode(game, "system/banner/animated")
.GetFormatAs<NodeContainerFormat>();
var animatedImage = new IconAnimation2AnimatedImage().Convert(animatedNode);
using var binaryGif = new AnimatedFullImage2Gif().Convert(animatedImage);
binaryGif.Stream.WriteTo("dump/icon.gif");
}