view minijss/jssmod.h @ 1896:f80b2dc77c30

Work begins on IFF ILBM/PBM image writer. It is pretty broken, some things will not work and some things are hardcoded. The ByteRun1 compression implementation is somewhat inefficient. Interleaved files do not work yet.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 26 Jun 2018 03:13:38 +0300
parents b47109fce375
children cedb5ca1533b
line wrap: on
line source

/*
 * miniJSS - Module structure and handling routines
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2006-2015 Tecnic Software productions (TNSP)
 */
#ifndef JSSMOD_H
#define JSSMOD_H

#include "jss.h"
#include "dmres.h"

#ifdef __cplusplus
extern "C" {
#endif

// Max data size definitions
#define jsetMaxChannels     (128)
#define jsetMaxRows         (16*1024) // Number of rows checked against
#define jsetDefaultRows     (64)      // Default number of rows in pattern
#define jsetMaxPatterns     (1024)    // Max patterns
#define jsetMaxInstruments  (1024)
#define jsetMaxOrders       (512)
#define jsetNNotes          (11 * 12)
#define jsetMinNote         (0)       // Smallest note number
#define jsetMaxNote         (jsetNNotes - 1)
#define jsetMaxEnvPoints    (64)      // Max number of envelope points

// Instrument envelope flags
#define jenvfUsed           (0x01)  // Envelope is used
#define jenvfSustain        (0x02)  // Envelope has a sustain point (XM) or has sustain loop (IT)
#define jenvfLooped         (0x04)  // Envelope is looped

// Instrument vibrato waveform types
#define jvibSine            (0)
#define jvibRamp            (1)
#define jvibSquare          (2)
#define jvibRandom          (3)

// General stuff
#define jsetNoteOff         (-2)
#define jsetOrderEnd        (-1)
#define jsetOrderSkip       (-2)


// General module flags
#define jmdfAmigaPeriods    (0x0001)    // Use non-linear periods (Amiga)
#define jmdfAmigaLimits     (0x0002)    // Use Amiga-styled valuelimits
#define jmdfStereo          (0x0008)    // Use stereo output, if possible

#define jmdfFT2Replay       (0x0010)    // Use FT2 replaying bugs/features
#define jmdfST300Slides     (0x0020)    // Use Scream Tracker 3.00 slides
#define jmdfByteLStart      (0x0040)    // LStart is in BYTES instead of WORDS (MOD only)


// Module format types
enum JMDT
{
    jmdtMOD = 1,
    jmdtS3M,
    jmdtXM,
    jmdtIT
};


// Bits for sample conversion routines
#define jsampDelta          (0x01)
#define jsampFlipSign       (0x02)
#define jsampSwapEndianess  (0x04)
#define jsampSplit          (0x08)

#define jsampHasData        (0x80) // Special flag


// Internal instrument structure
typedef struct
{
    int size,               // Length in units
        loopS,              // Loop start position in units
        loopE;              // Loop end position in units
    int volume,             // Volume [jsetMinVol...jsetMaxVol]
        flags,              // Flags - see jss.h jsfXXXX
        C4BaseSpeed,        // C4BaseSpeed
        ERelNote,           // Extended: Relative note value
        EFineTune,          // Extended: Fine-tune value
        EPanning;           // Extended: Panning
#ifndef JSS_LIGHT
    char *desc;
#endif
    void *data;             // Sample data

    int convFlags;
} JSSInstrument;


// Envelope point structure
typedef struct
{
    int frame, value;
} JSSEnvelopePoint;


// Envelope structure
typedef struct
{
    int flags,
        npoints,
        sustain,
        loopS,
        loopE;
    JSSEnvelopePoint points[jsetMaxEnvPoints];
} JSSEnvelope;


// Extended instrument
typedef struct
{
#ifndef JSS_LIGHT
    char *desc;
#endif
    int nsamples,
        sNumForNotes[jsetNNotes],
        *instConvTable;

    JSSEnvelope volumeEnv, panningEnv;
    int vibratoType,
        vibratoSweep,
        vibratoDepth,
        vibratoRate,
        fadeOut;
} JSSExtInstrument;


// Internal pattern structures
typedef struct
{
    int note,
        instrument,
        volume,
        effect,
        param;
} JSSNote;


typedef struct
{
    int nrows, nchannels;
    JSSNote *data;
} JSSPattern;


// Module structure
typedef struct
{
    int     moduleType;     // Type of the module
    char    *moduleName;    // Title/name
    char    *trackerName;   // Tracker software name
    int     defSpeed,       // Initial values
            defTempo,
            defFlags,
            defRestartPos,
            intVersion,     // Format's internal version
            nchannels,
            ninstruments,
            nextInstruments,
            npatterns,
            norders;

    int     defPanning[jsetNChannels];
    int     orderList[jsetMaxOrders];
    JSSPattern       *patterns[jsetMaxPatterns + 1];
    JSSInstrument    *instruments[jsetMaxInstruments];
    JSSExtInstrument *extInstruments[jsetMaxInstruments];

#ifdef JSS_SUP_THREADS
    DMMutex *mutex;
#endif

} JSSModule;


#ifdef JSS_SUP_JSSMOD

#define JSSMOD_VERSION    (0x20)

enum
{
    PATMODE_RAW_HORIZ = 1,
    PATMODE_COMP_HORIZ,
    PATMODE_RAW_VERT,
    PATMODE_COMP_VERT,
    PATMODE_RAW_ELEM,
    PATMODE_LAST
};

/* JSSMOD typedefs
 */
typedef struct __attribute__((__packed__))
{
    char  idMagic[2];       // "JM"
    Uint8 idVersion;        // 0x10 for 1.0, etc.
    Uint16
        defFlags,           // Flags field: see jmdf* flags
        intVersion,         // Internal version, format dependant
        norders,            // Number of orders in orderlist
        npatterns,          // Number of patterns
        nextInstruments,    // Number of extended instruments
        ninstruments,       // Number of sample-instruments
        defRestartPos;      // Default restart position in orderlist

    Uint8
        nchannels,          // Number of channels
        defSpeed,           // Default speed (ticks/row)
        defTempo,           // Default tempo (BPM)
        patMode;            // Pattern data format mode

    /*
    - After this, norders long orders table will follow, of type:
      Uint16 orderList[norders];

    - Pattern data, format depends on patMode.

    - Extended instruments (*)

    - Sample instrument headers (*)

    - Sample data (format depends) (*)

    (*) Items are optional and may have been omitted. Fields in the
        module and other headers are used to indicate if these items exist.
    */
} JSSMODHeader;


typedef struct __attribute__((__packed__))
{
    Uint16 frame, value;
} JSSMODEnvelopePoint;


typedef struct __attribute__((__packed__))
{
    Uint8
        flags,
        npoints,
        sustain,
        loopS,
        loopE;
    JSSMODEnvelopePoint points[jsetMaxEnvPoints];
} JSSMODEnvelope;


typedef struct __attribute__((__packed__))
{
    Uint8   nsamples,
            vibratoType;
    Uint16  vibratoSweep,
            vibratoDepth,
            vibratoRate,
            fadeOut;
    Uint32  sNumForNotes[jsetNNotes];  // 32bit because internally we use global indices
    JSSMODEnvelope volumeEnv, panningEnv;
} JSSMODExtInstrument;


typedef struct __attribute__((__packed__))
{
    Uint32  size,           // Length in units
            loopS,          // Loop start position in units
            loopE;          // Loop end position in units
    Uint16  flags,          // Flags - see jss.h jsfXXXX
            C4BaseSpeed;    // C4BaseSpeed
    Sint16  ERelNote,       // Extended: Relative note value
            EFineTune,      // Extended: Fine-tune value
            EPanning;       // Extended: Panning
    Uint8   volume,         // Volume [jsetMinVol...jsetMaxVol]
            convFlags;      // Conversion flags .. jsampXXXX
                            // jsampHasData set if there is sample data
} JSSMODInstrument;


#define JM_COMP_NOTE           (0x01)
#define JM_COMP_INSTRUMENT     (0x02)
#define JM_COMP_VOLUME         (0x04)
#define JM_COMP_EFFECT         (0x08)
#define JM_COMP_PARAM          (0x10)
#define JM_COMP_ALL (JM_COMP_NOTE | JM_COMP_INSTRUMENT | JM_COMP_VOLUME | JM_COMP_EFFECT | JM_COMP_PARAM)


typedef struct __attribute__((__packed__))
{
    Uint32 size;
    Uint16 nrows;
} JSSMODPattern;

#endif


#ifndef JSS_LIGHT
char *              jssASCIItoStr(const char *src, const char endByte, const size_t len);
BOOL                jssEncodeSample8(Uint8 *, const size_t, const int);
BOOL                jssEncodeSample16(Uint16 *, const size_t, const int);
#endif
int                 jssDecodeSample8(Uint8 *, const size_t, const int);
int                 jssDecodeSample16(Uint16 *, const size_t, const int);
int                 jssConvertModuleForPlaying(JSSModule *module);

JSSModule *         jssAllocateModule(void);
int                 jssFreeModule(JSSModule * module);

JSSPattern *        jssAllocatePattern(const int nrows, const int nchannels);
void                jssFreePattern(JSSPattern *pattern);

JSSInstrument *     jssAllocateInstrument(void);
void                jssFreeInstrument(JSSInstrument *inst);

JSSExtInstrument *  jssAllocateExtInstrument(void);
void                jssFreeExtInstrument(JSSExtInstrument *inst);

#ifdef JSS_SUP_XM
int        jssLoadXM(DMResource *file, JSSModule **pmodule, BOOL probe);
#endif

#ifdef JSS_SUP_JSSMOD
int        jssLoadJSSMOD(DMResource *file, JSSModule **pmodule, BOOL probe);
#endif


#ifdef __cplusplus
}
#endif

#endif // JSSMOD_H