Mercurial > hg > dmlib
view tools/lib64gfx.h @ 2597:f2fffa7b9137
Cosmetic.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 19 Nov 2023 03:55:18 +0200 |
parents | 0d6aa5cae517 |
children | 92909caccc9e |
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-2021 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 // Max defines #define D64_MAX_EXTRA_DATA 16 // Number of extraData slots #define D64_MAX_EXTRA_INFO 64 // Number of extraInfo slots // Bitmap constants #define D64_SCR_WIDTH 320 #define D64_SCR_HEIGHT 200 #define D64_SCR_CH_WIDTH (D64_SCR_WIDTH / 8) #define D64_SCR_CH_HEIGHT (D64_SCR_HEIGHT / 8) // Full screen size with borders #define D64_SCR_FULL_WIDTH 384 #define D64_SCR_FULL_HEIGHT 272 // Define the usually visible area #define D64_SCR_MIN_XC 32 #define D64_SCR_MAX_XC (D64_SCR_MIN_XC + D64_SCR_WIDTH) #define D64_SCR_MIN_YC 50 #define D64_SCR_MAX_YC (D64_SCR_MIN_YC + D64_SCR_HEIGHT) // C64 video screen pixel aspect ratio on PAL #define D64_SCR_PAR_XY (0.9365f) // Sprite constants #define D64_SPR_WIDTH_PX 24 #define D64_SPR_HEIGHT_PX 21 #define D64_SPR_WIDTH_UT (D64_SPR_WIDTH_PX / 8) // bytes #define D64_SPR_HEIGHT_UT D64_SPR_HEIGHT_PX #define D64_SPR_SIZE ((D64_SPR_WIDTH_UT * D64_SPR_HEIGHT_UT) + 1) #define D64_MAX_SPRITES 8 // Max sprites per scanline (in simple cases) // Character constants #define D64_CHR_WIDTH_PX 8 #define D64_CHR_HEIGHT_PX 8 #define D64_CHR_WIDTH_UT 1 // bytes #define D64_CHR_HEIGHT_UT 8 // lines #define D64_CHR_SIZE (D64_CHR_WIDTH_UT * D64_CHR_HEIGHT_UT) // Etc. #define D64_NCOLORS 16 #define D64_VIDBANK_SIZE (16*1024) #define D64_MAX_CHARS 256 // Different supported flags/modes enum { D64_FMT_HIRES = 0x000001, // Hi-res D64_FMT_MC = 0x000002, // MultiColor D64_FMT_ECM = 0x000003, // ECM mode (applies only to character mode) D64_FMT_MODE_MASK = 0x00000f, D64_FMT_ILACE = 0x000010, // Interlace D64_FMT_FLI = 0x000020, // FLI D64_FMT_CHAR = 0x000040, // Character mode D64_FMT_BORDER = 0x000080, // Uses border area D64_FMT_SPRITES = 0x000100, // Uses sprite layer }; // Different types of interlace enum { D64_ILACE_NONE = 0x000000, // Not set (invalid for interlaced images) D64_ILACE_RES = 0x000001, // Interlace doubles resolution D64_ILACE_COLOR = 0x000002, // Uses color mixing }; // Different types of interlace enum { D64_FLI_8 = 8, }; // Various extra settings (see DMC64Image::extraInfo[]) enum { D64_EI_MODE = 0, // Actual mode, if the format supports several D64_EI_CHAR_CASE, // [CHAR] 0 = upper case, != lower case D64_EI_CHAR_CUSTOM, // [CHAR] 0 = ROM charset, != custom charset D64_EI_FLI_TYPE, // FLI type (see D64_FLI_*) D64_EI_ILACE_TYPE, // Interlace type (see D64_ILACE_*) D64_EI_SPRBG_PRIORITY, // Sprite/background priority for 8 sprites (like $d01b) }; // Different enc/dec operation types (op->type) enum { DO_COPY, // Perform copy between memory (from/to offset) and subject DO_SET_MEM, // Set subject value or fill subject memory area to byte value from offset DO_SET_OP, // Like above but value from op->offs field instead DO_SET_MEM_HI, // Copy one byte value like DO_SET_MEM, but high nibble only DO_SET_MEM_LO, // Like above, but low nibble DO_FUNC, // Execute specified decoding / encoding function DO_CHAR_CFG, // Set character mode configuration DO_LAST, // Last opcode, end processing }; // "Subjects" of operations (DMC64EncDecOp::subject) enum { DS_COLOR_RAM, DS_BITMAP_RAM, DS_SCREEN_RAM, DS_EXTRA_DATA, DS_CHAR_DATA, DS_D020, DS_BGCOL, DS_D021, DS_D022, DS_D023, DS_D024, DS_EXTRA_INFO, DS_LAST }; // Operation flags (DMC64EncDecOp::flags) enum { DF_NORMAL = 0xffffff, DF_DECODE = 0x000001, DF_ENCODE = 0x000002, }; // Sprite flags (DMC64Sprite::flags) enum { D64_SPRF_MC = 0x000001, D64_SPRF_X_EXPAND = 0x000002, D64_SPRF_Y_EXPAND = 0x000004, }; typedef struct { char *name; char *desc; DMColor colors[D64_NCOLORS]; } DMC64Palette; typedef struct { DMPalette *pal; // Use this palette custom palette if != NULL DMC64Palette *cpal; // If DMC64ImageConvSpec::pal == NULL, use this C64 palette int xoffs, yoffs; // X/Y offsets in destination image int width, height; // Destination width/height (0 = use src) // XXX These are not actually used yet (if ever) bool borders; // Render borders (overrides width/height & aspect settings) bool aspect; // Render using pixel aspectX/aspectY, false = par=1:1 } DMC64ImageConvSpec; typedef struct { Uint8 *data; size_t size; } DMC64MemBlock; typedef struct { int xc, yc; // Sprite coordinates (XXX TODO: borders etc.) int flags; // D64_SPRF_* flags int color; // Color int sprnum; // Physical sprite number for priority checking Uint8 *data; // "const" pointer to sprite data, do not deallocate } DMC64Sprite; typedef struct { int xc, yc; // Sprite coordinates (XXX TODO: borders etc.) int flags; // D64_SPRF_* flags int color; // Color int sprnum; // Physical sprite number for priority checking int sprindex; // Index in "bank" int bank; // "Bank" of extraData where the data resides } DMC64SpriteDef; typedef struct _DMC64ImageCommonFormat DMC64ImageCommonFormat; typedef struct _DMC64ImageFormat DMC64ImageFormat; typedef struct _DMC64Image { DMC64ImageCommonFormat *fmt; int nblocks; // Number of internal blocks used // Bitmaps, color RAM, screen, etc. blocks * nblocks // Not all of them may be allocated DMC64MemBlock *color, *bitmap, *screen, *charData; // Other standard colours Uint8 d020, bgcolor, d022, d023, d024; // Extra data areas used by some formats, // for example raster colours might be stored DMC64MemBlock extraData[D64_MAX_EXTRA_DATA]; // Sprites int nsprites; DMC64Sprite *sprites; // Extra information / settings // See D64_EI_* constants. int extraInfo[D64_MAX_EXTRA_INFO]; } DMC64Image; typedef struct { Uint8 *col; } DMC64ScanLine; typedef int (*DMC64GetPixelFunc)(DMC64ScanLine *scan, const DMC64Image *img, const int rasterX, const int rasterY); typedef struct _DMC64EncDecOp { int type; // Operation type (DO_*) int subject; // Operation "subject" (DS_*) int offs; // Offset in "memory" int bank; // Bank number or extradata index size_t size; // Size of data (0 for "default") size_t blkoffs; // Offset in data-block int (*decFunction)(const struct _DMC64EncDecOp *op, DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageCommonFormat *fmt); int (*encFunction)(const struct _DMC64EncDecOp *op, DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageCommonFormat *fmt); int flags; // Operation flags (DF_*) } DMC64EncDecOp; #define D64_MAX_ENCDEC_OPS 32 typedef DMC64EncDecOp DMC64EncDecOpList[D64_MAX_ENCDEC_OPS]; typedef struct _DMC64ImageCommonFormat { int mode, // Format mode/type flags, see D64_FMT_* width, height, // Width and height in pixels chWidth, chHeight, // Width and height in charblocks aspectX, aspectY; // Pixel aspectX/Y (x=2 for multicolor, y=1 always) int (*convertFrom)(DMImage *dst, const DMC64Image *src, const DMC64ImageConvSpec *spec); int (*convertTo)(DMC64Image *dst, const DMImage *src, const DMC64ImageFormat *fmt, const DMC64ImageConvSpec *spec); DMC64GetPixelFunc getPixel; DMC64EncDecOpList encdecOps; } DMC64ImageCommonFormat; typedef struct _DMC64ImageFormat { char *fext; // Filename extension char *name; // Format description/name ssize_t addr; // Loading address ( -2 if no loading address, -1 if loading address not known) size_t size; // Size, including loading address. Only used in probing and encoding. size_t extra; // Extra data used for some formats int flags; // DM_FMT_* flags (read/write/broken/etc.), see libgfx.h int (*probe)(const DMGrowBuf *buf, const DMC64ImageFormat *fmt); int (*decode)(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt); int (*encode)(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt); DMC64ImageCommonFormat formatDef, *format; } DMC64ImageFormat; // // Compression types // enum { DM_COMP_RLE_MARKER = 1, // RLE with a separate marker byte DM_COMP_RLE_MASK = 2, // RLE that has marker bits and lower part acts as run length }; // Compression flags enum { DM_RLE_BYTE_RUNS = 0x0001, // Uses one-byte run lengths DM_RLE_WORD_RUNS = 0x0002, // Uses two-byte (word) run lengths DM_RLE_RUNS_MASK = 0x000f, DM_RLE_ORDER_1 = 0x0010, // Order: <marker>, <count/run length>, <data> DM_RLE_ORDER_2 = 0x0020, // Order: <marker>, <data>, <count/run length> DM_RLE_ORDER_MASK = 0x00f0, DM_RLE_BACKWARDS_INPUT = 0x0100, // Input is read backwards DM_RLE_BACKWARDS_OUTPUT = 0x0200, // Output is written backwards DM_RLE_ZERO_COUNT_MAX = 0x0400, // Zero "count" / run length value is max run (2^8, 2^16) DM_OUT_CROP_NONE = 0x0000, DM_OUT_CROP_START = 0x1000, DM_OUT_CROP_END = 0x2000, DM_OUT_CROP_MASK = 0xf000, }; typedef struct { char *func; size_t cropOutLen; int type; // DM_COMP_* int flags; // Uint8 // DM_COMP_RLE_MARKER mode rleMarkerB, // Marker byte for byte length runs (if DM_RLE_BYTE_RUNS used) rleMarkerW, // Marker byte for word length runs (if DM_RLE_WORD_RUNS used) // DM_COMP_RLE_MASK mode rleMarkerBits, rleMarkerMask, // Mask bits for marker: data & rleMarkerMask == rleMarkerBits rleCountMask; // Mask bits for length: count = data & rleCountMask unsigned int // Minimum and maximum run lengths rleMinCountB, rleMinCountW, rleMaxCountB, rleMaxCountW; } DMCompParams; // // Global variables // extern DMC64ImageFormat dmC64ImageFormats[]; extern const int ndmC64ImageFormats; extern DMC64ImageFormat **dmC64ImageFormatsSorted; // // Library init/close // int dmLib64GFXInit(void); void dmLib64GFXClose(void); // // Miscellaneous functions // int dmC64ProbeBMP(const DMGrowBuf *buf, const DMC64ImageFormat **fmt); int dmC64PaletteFromC64Palette(DMPalette **ppal, const DMC64Palette *cpal, const bool mixed); int dmC64SetImagePalette(DMImage *img, const DMC64ImageConvSpec *spec, const bool mixed); bool dmCompareAddr16(const DMGrowBuf *buf, const size_t offs, const Uint16 addr); int dmC64MemBlockAlloc(DMC64MemBlock *blk, const size_t size); int dmC64MemBlockCopy(DMC64MemBlock *dst, const DMC64MemBlock *src); void dmC64MemBlockFree(DMC64MemBlock *blk); // C64 bitmap image allocation/freeing DMC64Image *dmC64ImageAlloc(const DMC64ImageFormat *fmt); void dmC64ImageFree(DMC64Image *img); // Encoding and decoding of formats and images int dmC64ConvertCSDataToImage(DMImage *img, const int xoffs, const int yoffs, const Uint8 *buf, const int width, const int height, const bool multicolor, const int *colors); const char *dmC64GetOpSubjectName(const int subject); const DMC64MemBlock * dmC64GetOpMemBlock(const DMC64Image *img, const int subject, const int bank); int dmC64SanityCheckEncDecOp(const int i, const DMC64EncDecOp *op, const DMC64Image *img); int dmC64MemBlockAllocSubj(DMC64Image *img, const int subject, const int bank); size_t dmC64GetSubjectSize(const int subject, const DMC64ImageCommonFormat *fmt); size_t dmC64GetOpSubjectSize(const DMC64EncDecOp *op, const DMC64ImageCommonFormat *fmt); int dmC64DecodeGenericBMP(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt); int dmC64EncodeGenericBMP(const bool allocate, DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt); int dmC64ConvertBMP2Image(DMImage **pdst, const DMC64Image *src, const DMC64ImageConvSpec *spec); int dmC64ConvertImage2BMP(DMC64Image **pdst, const DMImage *src, const DMC64ImageFormat *fmt, const DMC64ImageConvSpec *spec); int dmC64DecodeBMP(DMC64Image **img, const DMGrowBuf *buf, ssize_t probeOffs, ssize_t dataOffs, const DMC64ImageFormat **fmt, const DMC64ImageFormat *forced); int dmC64EncodeBMP(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt); int dmGenericRLEAnalyze(const DMGrowBuf *buf, DMCompParams *cfg); void dmSetupRLEBuffers(DMGrowBuf *dst, DMGrowBuf *src, const DMCompParams *cfg); void dmFinishRLEBuffers(DMGrowBuf *dst, DMGrowBuf *src, const DMCompParams *cfg); int dmGenericRLEOutputRun(DMGrowBuf *dst, const DMCompParams *cfg, const Uint8 data, const unsigned int count); int dmEncodeGenericRLESequence(DMGrowBuf *dst, const Uint8 data, const unsigned int count, const DMCompParams *cfg); int dmDecodeGenericRLE(DMGrowBuf *dst, const DMGrowBuf *src, const DMCompParams *cfg); int dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const DMGrowBuf *src, const DMCompParams *cfg); int dmEncodeGenericRLE(DMGrowBuf *dst, const DMGrowBuf *src, const DMCompParams *cfg); int dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const DMGrowBuf *src, const DMCompParams *cfg); // // Macros for defining variables used in getpixel functions // #define DM_C64_GENERIC_SC_PIXEL_DEFS(ximg) \ const int \ x = rasterX / 8, \ y = rasterY / 8, \ yb = rasterY & 7, \ yoffs = y * ximg->fmt->chWidth, \ bmoffs = yoffs * 8 + yb + (x * 8), \ scroffs = yoffs + x, \ vshift = 7 - (rasterX & 7); #define DM_C64_GENERIC_MC_PIXEL_DEFS(ximg) \ const int \ x = rasterX / 4, \ y = rasterY / 8, \ yb = rasterY & 7, \ yoffs = y * (ximg)->fmt->chWidth, \ bmoffs = yoffs * 8 + yb + (x * 8), \ scroffs = yoffs + x, \ vshift = 6 - ((rasterX * 2) & 6); #define DM_C64_GENERIC_CHAR_PIXEL(ximg) \ const int \ x = rasterX / 8, \ y = rasterY / 8, \ scroffs = y * (ximg)->fmt->chWidth + x; \ // // Pixel format helpers // int dmC64GetGenericSCPixel(Uint8 *col, const DMC64Image *img, const int bmoffs, const int scroffs, const int vshift, const int vbank, const int bitmap); int dmC64GetGenericMCPixel(Uint8 *col, const DMC64Image *img, const int bmoffs, const int scroffs, const int vshift, const int vbank, const int bitmap, const int cbank, const int bgcolor); int dmC64GetGenericCharSCPixel(Uint8 *col, const DMC64Image *img, const int scroffs, const int rasterX, const int chrbank, const size_t chroffs, const int chr, const int cbank, const int bgcolor); int dmC64GetGenericCharMCPixel(Uint8 *col, const DMC64Image *img, const int scroffs, const int rasterX, const int chrbank, const size_t chroffs, const int chr, const int cbank, const int bgcolor, const int bgd022, const int bgd023); int dmC64GetGenericCharECMPixel(Uint8 *col, const DMC64Image *img, const int scroffs, const int rasterX, const int chrbank, const size_t chroffs, const int chr, const int cbank, const int bgcolor, const int bgd022, const int bgd023, const int bgd024); static inline const DMC64EncDecOp * fmtGetEncDecOp(const DMC64ImageFormat *fmt, const int index) { return &fmt->format->encdecOps[index]; } #ifdef __cplusplus } #endif #endif // LIB64GFX_H