Plays MaxTrax .mxtx Amiga modules (e.g. David A. Bean's Dark Seed score)
via a vendored port of ScummVM's portable MaxTrax player.
UADE is not the path: its amifilemagic.c detects the MXTX magic but
there is no MaxTrax eagleplayer upstream or in our vendored player set.
MaxTraxPlugin.{h,cpp}— the chipmachineChipPlugin/ChipPlayerwrapper.canHandlegates on themxtxextension and theMXTXcontent magic;getSamplesis a thin pass-through toPaula::readBuffer. Handles self-contained modules and split sets, resolved by content (a cheapprobe()counts scores/samples in a file's header):- A self-contained file (scores>0, samples>0) plays directly.
- A score-only file (samples==0) borrows the instrument bank of a sibling
.mxtxin the same directory that has samples. - An instrument-only bank (scores==0) borrows the scores of a sibling part.
The sibling is chosen by the longest shared filename prefix (then sample
count), so a score only pairs within its own set even when several sets share
a directory. This covers both the suffix split (Kyrandia
…scr/…inst) and the shared-bank split with no naming marker (Russell Lieblich's A-Train: many tiny score parts + one biga-train (intro).mxtxbank).load()is then called asload(score, scores=true, samples=false)+load(inst, false, true). When streaming (no local mirror), the bank's filename usually can't be derived from a score part, sogetSecondaryFilesprobes the primary and, for any split half, returns the sentinel"./"— asking the host (MusicPlayerList) to list the song's own directory and fetch every sibling next to it, so the bank lands in the cache dir forfromFile's scan. (MusicPlayerListwas extended with a"./"= current-directory case alongside the existing subdir sentinel used by IFF-SMUSInstruments/.) A self-contained module requests nothing.
maxtrax/maxtrax.{h,cpp}— score/sample loader + sequencer (ScummVM, GPLv3)maxtrax/paula.{h,cpp}— Amiga Paula mixer (ScummVM, GPLv3)maxtrax/compat.h— small shim replacing the ScummVM deps (Common::SeekableReadStream,Common::Mutex,frac_t,MIN/MAX/CLIP,debug/warning) so the two files build standalone.maxtrax/poc_main.cpp— standalone decode→WAV harness (not built by CMake).
maxtrax.h: upstreamENABLE_KYRA/DYNAMIC_MODULESgate replaced with a plain include guard; addedgetScoreCount().#includeof paula →"paula.h".paula.h:class Paula : public AudioStream→class Paula; includes →compat.h;Common::Mutex &_mutex→ value member.paula.cpp: includes →compat.h+paula.h; dropped_mutex(g_system->getMixer()->mutex())from the ctor init list; deleted theAmigaMusicPlugin/REGISTER_PLUGIN_STATICblock.maxtrax.cpp: ScummVM includes →compat.h+maxtrax.h.
Single combined module, all big-endian: MXTX magic, uint16 tempo, uint16
flags (bit0 lowpass filter, bit1 attack-volume, bit15 microtonal), optional
microtonal block, uint16 score count + scores (6-byte events), uint16
sample count + sample patches (envelopes + 8-bit signed PCM).
cd maxtrax
clang++ -std=c++17 -O2 poc_main.cpp paula.cpp maxtrax.cpp -o maxtrax_poc
./maxtrax_poc darkseed_00.mxtx out.wav 12 0The vendored MaxTrax/Paula sources are GPL-3-or-later (ScummVM).
Plus build only. Because of that licence this plugin is NOT compiled into the
Mac App Store variant: CM_VARIANT=mas sets CM_HAVE_MAXTRAX=OFF, so the target
is not built and maxtraxplugin_register() is #ifdef'd out
(CM_NO_MAXTRAX). The 93 .mxtx rows are dropped from that variant's index to
match — .mxtx is sole-claimed (vgmstream names it only to decline it), so the
plain extension test in songHasNoPlayer() covers the modland rows and
nameHasPlayer()'s leading-token branch covers the UnExoticA mxtx.<song>
prefix form; no formatPlayer key is needed.
Nothing replaces it there: ScummVM's is the only native MaxTrax implementation
that exists, every other player is unlicensed 68k assembly (Wanted Team's
EaglePlayer), and a .mxtx carries no replayer of its own, so the sc68/SNDH
"emulate the original driver" route is closed too. See CM_HAVE_MAXTRAX in
chipmachine/CMakeLists.txt for the full reasoning and the clean-room estimate,
and chipmachine/LEGAL-PLUS.