view minijss/jssmod.h @ 2279:fc58f62f100c

Bump copyright years.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 18 Jun 2019 12:12:58 +0300
parents 40ccc09f09be
children dcf1016f3d27
line wrap: on
line source

/*
 * miniJSS - Module structure and handling routines
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2006-2019 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, nmap;
    BOOL *used;
    Uint8 *map;
    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    (0x30)

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

/* JSSMOD typedefs
 */
typedef struct
{
    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
{
    Uint16 frame, value;
} JSSMODEnvelopePoint;


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


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


typedef struct
{
    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
{
    Uint32 size;
    Uint16 nrows;
    Uint16 nchannels; // may differ from JSSMODHeader::nchannels
    // IF nchannels != JSSMODHeader::nchannels, then:
    // Uint8 map[JSSMODPattern::nchannels];
} JSSMODPattern;

#endif


#ifndef JSS_LIGHT
char *              jssASCIItoStr(const char *src, const char endByte, const size_t len);
int                 jssEncodeSample8(Uint8 *, const size_t, const int);
int                 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