This document describes the basics of writing a new module loader and related work that has to be done. We will not discuss in detail how to write the loader, have a look at existing loaders to get an idea how they work in general.
MODTYPE
flag, unless it can be reasonably
represented as a subset of another format (like Ice Tracker ICE files being
a subset of ProTracker MOD).common/Endianness.h
:
Entire structs containing integers with defined endianness can be read in one
go if they are tagged with MPT_BINARY_STRUCT
(see existing loaders for an
example).
CSoundFile::m_nChannels
MUST NOT be changed after a pattern has been
created, as existing patterns will be interpreted incorrectly. For module
formats that support per-pattern channel amounts, the maximum number of
channels must be determined beforehand.FileReader::ReadString
and friends for reading them directly from a filempt::String::ReadBuf
for reading them from a struct or char arrayThese functions take care of string padding (zero / space padding) and will avoid reading past the end of the string if there is no terminating null character.
FileReader
instances may be used to treat a portion of a file as its own
independent file (through FileReader::ReadChunk
). This can be useful with
"embedded files" such as WAV or Ogg samples. Container formats such as UMX
are another good example for this usage.MODTYPE
to CSoundFile::UseFinetuneAndTranspose
if applicable,
and see if any effect handlers in soundlib/Snd_fx.cpp
need to know the new
MODTYPE
.std::size
(or mpt::array_size
in contexts where std::size
is not
usable) or, for ensuring that char arrays are null-terminated,
mpt::String::SetNullTerminator
. Similarly, do not assume any specific
quantities for OpenMPT's constants like MAX_SAMPLES, MAX_PATTERN_ROWS, etc.
These may change at any time.CSoundFile::CanAddMoreSamples
and CSoundFile::CanAddMoreInstruments
to
check if a given amount of samples or instruments can be added to the file
rather than doing the calculations yourself.ModuleFormatLoaders
array in
Sndfile.cpp depends on various factors. In general, module formats that have
very bad magic numbers (and thus might cause other formats to get
mis-interpreted) should be placed at the bottom of the list. Two notable
examples are 669 files, where the first two bytes of the file are "if"
(which may e.g. cause a song title starting with if ..." in various other
formats to be interpreted as a 669 module), and of course
Ultimate SoundTracker modules, which have no magic bytes at all.libopenmpt provides fast probing functions that can be used by library users to quickly check if a file is most likely playable with libopenmpt, even if only a fraction of the file is available (e.g. when streaming from the internet).
In order to satisfy these requirements, probing functions should do as little
work as possible (e.g. only parse the header of the file), but as much as
required to tell with some certainty that the file is really of a certain mod
format. However, probing functions should not rely on having access to more than
the first CSoundFile::ProbeRecommendedSize
bytes of the file.
CSoundFile::ProbeAdditionalSize
must not be higher than the biggest size
that would cause a hard failure (i.e. returning false
) in the module loader.Apart from writing the module loader itself, there are a couple of other places that need to be updated:
build/android_ndk/Android.mk
.build/autotools/Makefile.am
.build/regenerate_vs_projects.sh
/ build/regenerate_vs_projects.cmd
(depending on your platform)installer/filetypes-*.iss
.CTrackApp::OpenModulesDialog
in mptrack/Mptrack.cpp
.soundlib/Tables.cpp
.