view tools/lib64gfx.h @ 1545:3b613fcbf3ff

Improve how format read/write capabilities are marked and shown.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 12 May 2018 21:01:46 +0300
parents 776aa43b2c57
children 86373ac0861a
line wrap: on
line source

/*
 * Functions for reading and converting various restricted
 * C64/etc and/or indexed/paletted graphics formats.
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2012-2018 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 */
#ifndef LIB64GFX_H
#define LIB64GFX_H 1

#include "libgfx.h"
#include "dmgrowbuf.h"

#ifdef __cplusplus
extern "C" {
#endif


// Bitmap constants
#define C64_SCR_WIDTH          320
#define C64_SCR_HEIGHT         200
#define C64_SCR_CH_WIDTH       (C64_SCR_WIDTH/8)
#define C64_SCR_CH_HEIGHT      (C64_SCR_HEIGHT/8)
#define C64_SCR_COLOR_SIZE     (C64_SCR_CH_WIDTH * C64_SCR_CH_HEIGHT)
#define C64_SCR_SCREEN_SIZE    (C64_SCR_CH_WIDTH * C64_SCR_CH_HEIGHT)
#define C64_SCR_BITMAP_SIZE    ((C64_SCR_WIDTH * C64_SCR_HEIGHT)/8)
#define C64_MAX_EXTRA_DATA     64

// C64 video screen pixel aspect ratio on PAL
#define C64_SCR_PAR_XY         (0.9365f)

// Sprite constants
#define C64_SPR_WIDTH          3 // bytes
#define C64_SPR_HEIGHT         21 // lines
#define C64_SPR_WIDTH_PX       (8 * C64_SPR_WIDTH)
#define C64_SPR_SIZE           ((C64_SPR_WIDTH * C64_SPR_HEIGHT) + 1)

// Character constants
#define C64_CHR_WIDTH          1 // bytes
#define C64_CHR_HEIGHT         8 // lines
#define C64_CHR_WIDTH_PX       (8 * C64_CHR_WIDTH)
#define C64_CHR_SIZE           (C64_CHR_WIDTH * C64_CHR_HEIGHT)

// Etc.
#define C64_RAM_SIZE           (64*1024)
#define C64_NCOLORS            16
#define C64_MAX_COLORS         16
#define C64_VIDBANK_SIZE       (16*1024)
#define C64_MAX_SPRITES        (C64_VIDBANK_SIZE / C64_SPR_SIZE)
#define C64_MAX_CHARS          256


#define DM_GET_ADDR_LO(addr) ((addr) & 0xff)
#define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff)


// Different supported C64 bitmap "modes"
enum
{
    D64_FMT_HIRES        = 0x0000,
    D64_FMT_MC           = 0x0001,
    D64_FMT_ILACE        = 0x0002,
    D64_FMT_FLI          = 0x0004,
    D64_FMT_CHAR         = 0x0008,

    D64_FMT_MODE_MASK    = 0x000f,

};

enum
{
    D64_ILACE_RES,
    D64_ILACE_COLOR,
};


// Charmode screen memory configuration
enum
{
    D64_CHCFG_SCREEN,      // Use screen memory
    D64_CHCFG_LINEAR = 1,  // Generate linear pattern so that first line
                           // of chars is 0-39, second 40-79, up to 255.
};


typedef struct
{
    BOOL multicolor, xexpand, yexpand;
    int color, xc, yc;
    Uint8 data[C64_SPR_HEIGHT][C64_SPR_WIDTH];
} DMC64Sprite;


enum
{
    DC_D020,
    DC_BGCOL,
    DC_D021,
    DC_D022,
    DC_D023,
    DC_D024,
};


typedef struct _DMC64Image
{
    int type,       // Image type (D64_FMT_*)
        laceType,   // Interlace type (D64_ILACE_*)
        nbanks;

    int width, height; // Width and height in pixels
    int chWidth, chHeight; // Width and height in charblocks

    size_t
        screenSize,
        bitmapSize,
        charmemSize;

    Uint8
        **color,
        **bitmap,
        **screen,
        **charmem,
        *extraData[C64_MAX_EXTRA_DATA],
        d020, bgcolor, d022, d023, d024;

    size_t extraDataSizes[C64_MAX_EXTRA_DATA];

    DMC64Sprite sprites[C64_MAX_SPRITES];
} DMC64Image;


typedef Uint8 (*DMC64GetPixelFunc)(
    const DMC64Image *img, const int bmoffs, const int scroffs,
    const int vshift, const int vbitmap, const int raster);

enum
{
    DT_COLOR_RAM,
    DT_BITMAP,
    DT_SCREEN_RAM,
    DT_COLOR_REG,
    DT_COLOR_SET,
    DT_EXTRA_DATA,

    DT_DEC_FUNCTION,
    DT_ENC_FUNCTION,

    DT_CHAR_DATA,
    DT_CHAR_CONFIG,

    DT_LAST,
};


#define D64_MAX_ENCDEC_OPS 64


typedef struct _DMC64ImageFormat DMC64ImageFormat;

typedef struct _DMC64EncDecOp
{
    int    type;
    size_t offs;
    int    bank;
    size_t size;
    BOOL   (*decFunction)(DMC64Image *img, const struct _DMC64EncDecOp *op, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt);
    BOOL   (*encFunction)(const struct _DMC64EncDecOp *op, DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt);
} DMC64EncDecOp;


typedef struct _DMC64ImageFormat
{
    int  type;   // Type flags, see D64_FMT_*
    char *fext;  // Filename extension
    char *name;  // Format description/name

    size_t addr; // Loading address (0 if no loading address)
    size_t size; // Size, including loading address. Only used in probing and encoding.

    int  flags;  // DM_FMT_* flags, see libgfx.h

    int width, height; // Width and height in pixels
    int chWidth, chHeight; // Width and height in charblocks

    int  (*probe)(const Uint8 *buf, const size_t len, const struct _DMC64ImageFormat *fmt);

    int  (*decode)(DMC64Image *img, const Uint8 *buf, const size_t len, const struct _DMC64ImageFormat *fmt);
    int  (*encode)(DMGrowBuf *buf, const DMC64Image *img, const struct _DMC64ImageFormat *fmt);

    int  (*convertFrom)(DMImage *, const DMC64Image *, const struct _DMC64ImageFormat *fmt);
    int  (*convertTo)(DMC64Image *, const DMImage *, const struct _DMC64ImageFormat *fmt);

    DMC64GetPixelFunc getPixel;

    DMC64EncDecOp encdecOps[D64_MAX_ENCDEC_OPS];
} DMC64ImageFormat;


#define DM_COMP_RLE_MARKER    1
#define DM_COMP_RLE_MASK      2


typedef struct
{
    int type;
    Uint8 rleMarker, rleMask1, rleMask2, rleMinCount, rleMaxCount;
} DMCompParams;


//
// Global variables
//
extern DMColor           dmDefaultC64Palette[C64_NCOLORS];
extern const DMC64ImageFormat  dmC64ImageFormats[];
extern const int         ndmC64ImageFormats;


//
// Miscellaneous functions
//
void      dmC64ImageDump(FILE *fh, const DMC64Image *img, const DMC64ImageFormat *fmt);
void      dmSetDefaultC64Palette(DMImage *img);
char *    dmC64GetImageTypeString(char *buf, const size_t len, const int type, const BOOL lng);
int       dmC64ConvertCSDataToImage(DMImage *img, int xoffs, int yoffs, const Uint8 *inBuf, int width, int height, BOOL multicolor, int *colors);
int       dmC64ImageGetNumBanks(const DMC64ImageFormat *fmt);
BOOL      dmCompareAddr16(const Uint8 *buf, const size_t offs, const Uint16 addr);
int       dmC64SanityCheckEncDecOp(const int i, const DMC64EncDecOp *op, const DMC64Image *img);
BOOL      dmC64GetOpSize(const DMC64EncDecOp *op, const DMC64ImageFormat *fmt, size_t *size);


// C64 bitmap image allocation/freeing
DMC64Image *dmC64ImageAlloc(const DMC64ImageFormat *fmt);
void      dmC64ImageFree(DMC64Image *img);


// Encoding and decoding of formats and images
int       dmC64ProbeBMP(const Uint8 *buf, const size_t len, const DMC64ImageFormat **fmt);

int       dmC64DecodeGenericBMP(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt);
int       dmC64EncodeGenericBMP(const BOOL allocate, DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt);

int       dmC64ConvertBMP2Image(DMImage **pdst, const DMC64Image *src, const DMC64ImageFormat *fmt);
int       dmC64ConvertImage2BMP(DMC64Image **pdst, const DMImage *src, const DMC64ImageFormat *fmt);

int       dmC64DecodeBMP(DMC64Image **img, const Uint8 *buf, const size_t len, const size_t probeOffs, const size_t loadOffs, const DMC64ImageFormat **fmt, const DMC64ImageFormat *forced);
int       dmC64EncodeBMP(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt);

int       dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src, const DMC64ImageFormat *fmt);
int       dmC64ConvertGenericImage2BMP(DMC64Image *dst, const DMImage *src, const DMC64ImageFormat *fmt);

void      dmGenericRLEAnalyze(const DMGrowBuf *buf, Uint8 *rleMarker, const int rleType);

int       dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const DMCompParams *cfg);
int       dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const DMCompParams *cfg);

int       dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const DMCompParams *cfg);
int       dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const DMCompParams *cfg);


//
// Inline helper functions for pixel format decoding
//
static inline Uint8 dmC64GetGenericSCPixel(
    const DMC64Image *img, const int bmoffs, const int scroffs,
    const int vshift, const int vbank, const int vbitmap, const int cbank)
{
    (void) cbank;
    if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1)
        return img->screen[vbank][scroffs] >> 4;
    else
        return img->screen[vbank][scroffs] & 15;
}


static inline Uint8 dmC64GetGenericMCPixel(
    const DMC64Image *img, const int bmoffs, const int scroffs,
    const int vshift, const int vbank, const int vbitmap, const int cbank)
{
    switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3)
    {
        case  0: return img->bgcolor; break;
        case  1: return img->screen[vbank][scroffs] >> 4; break;
        case  2: return img->screen[vbank][scroffs] & 15; break;
        default: return img->color[cbank][scroffs] & 15; break;
    }
}


static inline Uint8 fmtGetGenericSCPixel(
    const DMC64Image *img, const int bmoffs, const int scroffs,
    const int vshift, const int vbitmap, const int raster)
{
    (void) raster;
    return dmC64GetGenericSCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0);
}


static inline Uint8 fmtGetGenericMCPixel(
    const DMC64Image *img, const int bmoffs, const int scroffs,
    const int vshift, const int vbitmap, const int raster)
{
    (void) raster;
    return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0);
}


#ifdef __cplusplus
}
#endif

#endif // LIB64GFX_H