view sidlib.h @ 341:fe061ead51cc

Perform character set conversion after item formatting step instead of before it. This should remedy the potential issue of formatting not taking UTF8 multibyte into account, as our formatting unfortunately does not support multibyte encoding. This way the data should stay in ISO-8859-1 format just up to outputting it.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 13 Jan 2020 16:29:47 +0200
parents 6d0143e43edf
children 4978ff445572
line wrap: on
line source

/*
 * SIDInfoLib - Way too simplistic PSID/RSID file library
 * Programmed and designed by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
 * (C) Copyright 2014-2020 Tecnic Software productions (TNSP)
 */
#ifndef SIDLIB_H
#define SIDLIB_H 1

#include "th_util.h"
#include "th_ioctx.h"
#include "th_crypto.h"
#include "th_datastruct.h"


#ifdef __cplusplus
extern "C" {
#endif


//
// Some constants
//
#define SIDLIB_PSID_MAGIC_LEN    (4)
#define SIDLIB_PSID_STR_LEN      (32)
#define SIDLIB_BUFFER_SIZE       (1024 * 16)


enum
{
    // Player flags
    PSF_PLAYER_TYPE   = 0x01, // 0 = built-in, 1 = Compute! SIDPlayer MUS
    PSF_PLAYSID_TUNE  = 0x02, // 0 = Real C64-compatible, 1 = PlaySID specific (v2NG)

    // Video standard used (v2NG+)
    PSF_CLOCK_UNKNOWN = 0x00,
    PSF_CLOCK_PAL     = 0x01,
    PSF_CLOCK_NTSC    = 0x02,
    PSF_CLOCK_ANY     = 0x03,
    PSF_CLOCK_MASK    = 0x03,

    // SID model (v2NG+)
    PSF_MODEL_UNKNOWN = 0x00,
    PSF_MODEL_MOS6581 = 0x01,
    PSF_MODEL_MOS8580 = 0x02,
    PSF_MODEL_ANY     = 0x03,
    PSF_MODEL_MASK    = 0x03,
};


// STIL database subtune fields, see SIDLibSTILSubTune
enum
{
    STF_NAME,
    STF_AUTHOR,
    STF_TITLE,
    STF_INFO,
    STF_ARTIST,
    STF_COMMENT,

    STF_LAST
};


//
// Structures
//
typedef struct
{
    th_llist_t node;

    th_md5hash_t    hash;       // MD5 hash-digest
    int             nlengths;   // Number of lengths
    int             *lengths;   // Lengths in seconds
} SIDLibSLDBNode;


typedef struct
{
    SIDLibSLDBNode  *nodes, **pindex;
    size_t nnodes;
} SIDLibSLDB;


typedef struct
{
    int ndata;
    char **data;  // Converted through SIDLibChConvCtx if conversion is used
} SIDLibSTILField;


typedef struct
{
    int tune; // Subtune number this structure contains information for
    SIDLibSTILField fields[STF_LAST];
} SIDLibSTILSubTune;


typedef struct
{
    th_llist_t node;

    char *filename;    // HVSC path/filename (NOT converted through SIDLibChConvCtx)
    size_t nsubtunes;  // Number of subtune information structures
    SIDLibSTILSubTune *subtunes; // NOTE! Subtunes are in undefined order here
        // (through with correct SIDLibSTILSubTune::tune number, of course)
        // unless sidlib_stildb_build_index() has been run on the SIDLibSTILDB

    // Internal use only
    SIDLibSLDBNode *lengths;
} SIDLibSTILNode;


typedef struct
{
    SIDLibSTILNode *nodes, **pindex;
    size_t nnodes;
} SIDLibSTILDB;


typedef struct
{
    char magic[SIDLIB_PSID_MAGIC_LEN + 1]; // "PSID" / "RSID" magic identifier
    uint16_t
        version,         // Version number
        dataOffset,      // Start of actual c64 data in file
        loadAddress,     // Loading address
        initAddress,     // Initialization address
        playAddress,     // Play one frame
        nSongs,          // Number of subsongs
        startSong;       // Default starting song
    uint32_t speed;      // Speed

    char *sidName;       // Descriptive text-fields, ASCIIZ
    char *sidAuthor;     // Converted through SIDLibChConvCtx if conversion is used
    char *sidCopyright;

    // PSIDv2+ data
    uint16_t flags;      // Flags
    uint8_t  startPage, pageLength;
    uint8_t  sid2Addr, sid3Addr;

    // Extra data
    BOOL isRSID;
    size_t dataSize;     // Total size of data - header
    th_md5hash_t hash;   // Songlength database hash

    // Internal use only
    BOOL allocated; // TRUE if structure has been allocated
    SIDLibSLDBNode *lengths; // Songlength information node pointer
    SIDLibSTILNode *stil;  // STIL database node pointer
} SIDLibPSIDHeader;


typedef struct SIDLibChConvCtx
{
    void *data;
    char* (*convert)(struct SIDLibChConvCtx *ctx, const char *str);
} SIDLibChConvCtx;


//
// Globals
//
const char *     sidlib_stil_fields[STF_LAST];


//
// Functions
//
int              sidlib_read_sid_file(th_ioctx *ctx, SIDLibPSIDHeader *psid, const BOOL newSLDB, SIDLibChConvCtx *chconv);
int              sidlib_read_sid_file_alloc(th_ioctx *ctx, SIDLibPSIDHeader **ppsid, const BOOL newSLDB, SIDLibChConvCtx *chconv);
void             sidlib_free_sid_file(SIDLibPSIDHeader *psid);

const char *     sidlib_get_sid_clock_str(const int flags);
const char *     sidlib_get_sid_model_str(const int flags);

int              sidlib_sldb_new(SIDLibSLDB **pdbh);
int              sidlib_sldb_read(th_ioctx *ctx, SIDLibSLDB *dbh);
int              sidlib_sldb_build_index(SIDLibSLDB *dbh);
void             sidlib_sldb_free(SIDLibSLDB *dbh);
SIDLibSLDBNode * sidlib_sldb_get_by_hash(SIDLibSLDB *dbh, th_md5hash_t hash);

int              sidlib_stildb_new(SIDLibSTILDB **pdbh);
int              sidlib_stildb_read(th_ioctx *ctx, SIDLibSTILDB *dbh, SIDLibChConvCtx *chconv);
int              sidlib_stildb_build_index(SIDLibSTILDB *dbh);
void             sidlib_stildb_free(SIDLibSTILDB *dbh);
SIDLibSTILNode * sidlib_stildb_get_node(SIDLibSTILDB *dbh, const char *filename);
SIDLibSTILSubTune *sidlib_stildb_find_subtune(SIDLibSTILNode *node, const int nsubtune);


#ifdef __cplusplus
}
#endif
#endif // SIDLIB_H