-
Notifications
You must be signed in to change notification settings - Fork 60
Kontract
Kontract contains all interfaces that can be inherited by plugins to ensure proper communication between them and Kore. It ensures file operations and format type specific interactions.
This state implements an IList<IArchiveFileInfo>
property named "Files", which may hold the files loaded from the archive file format. It is recommended to use a SubStream as the FileData
stream to reduce memory usage.
The ArchiveFileInfo
is a class offering the base logic for a single file in a typical archive file format and already implement IArchiveFileInfo
.
It is recommended to use ArchiveFileInfo
, as it already implements most basic needs for a single file in our framework. However, you can create your own implementation of IArchiveFileInfo
to add different or more specific logic you may require.
The class implements the methods GetFileData
and SetFileData
to get and set the FileData
stream and its internal dependencies, such as compression management.
It also implements a method SaveFileData
which writes the FileData
stream to a given stream and its current position.
The class can take in a Stream
representing the files data and a UPath
representing the file path.
Additionally to that, it can also take in an IKompressionConfiguration
and int
representing the decompressed size of the data, which allows for a known decompression to be applied to the stream when needed.
More information on IKompressionConfiguration
and how it is used to implement compression algorithms in general, can be found at Kompression.
This state implements an IList<IKanvasImage>
property named "Images". It may hold all images the file contains, and their mipmaps.
This state implements an EncodingDefinition
property named "EncodingDefinition". It may hold pairs of integral values to their respective IColorEncoding
or IIndexEncoding
.
The state and its logic are designed to let the developer do as less manual work with the image as possible, but also give them as much control as necessary to change the decoding/encoding pipeline used by the framework.
The IKanvasImage
is implemented by KanvasImage
found in Kanvas. It wraps around an ImageInfo
and implements all necessary logic to decode and encode an image given by the ImageInfo
with the EncodingDefinition
.
The ImageInfo
contains the raw image information needed to describe a full image.
It may contain the raw pixel data as bytes named ImageData
,
the integral value into the EncodingDefinition named ImageFormat
, and
the size of the image named Size
.
If necessary, ImageInfo
may also contain the raw pixel data as bytes for the palette named PaletteData
, and
the integral value into the EncodingDefinition named PaletteFormat
to decode the palette.
Optionally, an ImageInfo
may also contain the raw pixel data as bytes named MipMapData
for each mip map the image might describe.
Configuration
may only be set and used, if the default pipeline of the framework has to change.
For example, a developer may set a Swizzle (better known as PixelRemap) depending on the platform the image format is supposed to come from.
Kanvas already implements well-known Swizzles for the platforms NDS, 3DS, PSVita, and WiiU.
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Drawing;
using System.Linq;
using System.IO;
using Kontract.Interfaces.Plugins.State;
using Kontract.Interfaces.FileSystem;
using Kontract.Models.Image;
using Kontract.Models.IO;
using Kontract.Models.Context;
using Kontract.Kanvas;
using Kanvas;
using Kanvas.Encoding;
public class State : IImageState, ILoadFiles
{
public EncodingDefinition EncodingDefinition { get; }
public IList<IKanvasImage> Images { get; }
public State()
{
EncodingDefinition = new EncodingDefinition();
EncodingDefinition.Add(0, new Rgba(8, 8, 8, 8)); // Defines that integral value 0 connects to encoding RGBA8888
}
public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext)
{
[... Load file from file system]
var imageInfos = LoadImageInfos(file);
Images = imageInfos.Select(info => new KanvasImage(EncodingDefinition, info)).ToArray();
}
private IList<ImageInfo> LoadImageInfos(Stream file)
{
[... Read file to retrieve actual information]
// This creates an image info, which may contain information read from the file
// This image info may contain an image of size (1,1) and containing one black pixel encoded with RGBA8888
var imageInfo = new ImageInfo(new byte[4], 0, new Size(1, 1));
return new List<ImageInfo>{ imageInfo };
}
}
Disclaimer: Explanations to text plugins is deprecated and refers to an older version of the framework.
This interface implements an IEnumerable in the plugin, which should hold all text from a text format.
Additionally this interface implements the following:
- NameFilter; a regular expression that the TextEntry name must match with
- NameMaxLength; the maximum length of TextEntry names
- LineEndings; the line ending the format uses to begin a new line
TextEntry is a class that is used in all text format interfaces. It inherits from INotifyPropertyChanged and declares an own even Edited
.
It implements the following properties:
- Name; Virtual; A name or title for the text entry
- OriginalText; Virtual; The original text of the entry, that shouldn't change even after editing
- EditedText; Virtual; The edited text, which can get changed over time
- Notes; Virtual; It's possible to add notes per entry for translation purposes
- MaxLength; Virtual; The max length of OriginalText and EditedText
- CanEdit; Virtual; Determines whether the text can be edited
Every property beside MaxLength and CanEdit toggle both events.
This interface is an addition to text plugins and currently the only non file-based plugin type in Kuriimu2. Those game plugins are meant to create image previews of TextEntry's. They are also meant to handle control codes of the text and change the preview accordingly.
This plugin type is more user- and UI-oriented and therefore less attractive to independant developers. For a programmer of a dedicated translation team though, it will be a helpful addition for their translators to see their work as ingame previews.
The interface implements the following properties:
- ID; A unique Id for the plugin
- Name; A name for the plugin; This information can be shown on UIs to select them for example
- IconPath; An icon for the plugin; Can be shown on UI for better visualization
- FileName; Name of the file that is opened by the text plugin the Entries come from
- Entries; The TextEntry's that were loaded into the game plugin
The interface implements a method Loadentries(IEnumerable<TextEntry> entries)
which should set Entries
and might do stuff like control code interpreting.
It also implements a method SaveEntries()
which writes everything back to their respective TextEntry's and returns an IEnumerable.
This interface implements a method GeneratePreview(TextEntry entry)
which should generate an image preview out of the given TextEntry.
There are many more type interfaces planned, but not yet implemented or thoroughly developed. Planned are IArchiveAdapter, ILayoutAdapter and IFontAdapter.
While IFontAdapter was the first type interface developed for Kuriimu2s proof-of-concept, it's still considered incomplete and will be documented at a later point. You might want to trial-and-error with it, if you still want to work with it.
Those interfaces ensure basic file functionality for the plugin. It isn't specific to any format type and can be used for any file-based plugins.
This interface implements a method Identify(string filename)
. It returns a boolean, indicating if the plugin can handle the given file or not.
If a plugin doesn't inherit from this interface, Kore will handle it as a blind plugin.
This interface implements a method Load(string filename)
. This method should open and interpret the given file.
This interface implements a method Save(string filename, int versionIndex = 0)
. This method is meant to save the interpreted data back into the file format. The versionIndex is meant to differentiate between versions of a file format, but is currently unused by Kore.
This interface implements a method Create()
. This method is meant to create the format from scratch, without loading a file beforehand.