view dmlib.h @ 0:32250b436bca

Initial re-import.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 28 Sep 2012 01:54:23 +0300
parents
children 10f58ff516b3
line wrap: on
line source

/*
 * DMLib
 * -- Main header file
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2011 Tecnic Software productions (TNSP)
 */
#ifndef DMLIB_H
#define DMLIB_H

#include <SDL.h>
#ifdef DM_GFX_TTF_TEXT
#include <SDL_ttf.h>
#endif
#include <stdarg.h>

#ifdef DM_USE_ASSERTS
#include <assert.h>
#else
#define assert(NEXPR) // stub
#endif

#ifdef __cplusplus
extern "C" {
#endif

// Defaults
//#define DM_PROG_AUTHOR      "By Matti 'ccr' Hmlinen (C) Copyright 2012 TNSP"
//#define DM_PROG_LICENSE     "This software is licensed under GNU GPL version 2"

#define DM_PROG_AUTHOR      ""
#define DM_PROG_LICENSE     ""

/* Error codes
 */
enum {
	// General error codes
	DMERR_OK = 0,
	DMERR_FOPEN,
	DMERR_FREAD,
	DMERR_FWRITE,
	DMERR_FSEEK,
	DMERR_NOT_FOUND,

	DMERR_INVALID_DATA,
	DMERR_MALLOC,
	DMERR_ALREADY_INIT,
	DMERR_INIT_FAIL,
	DMERR_INVALID_ARGS,

	DMERR_NULLPTR,
	DMERR_NOT_SUPPORTED,
	DMERR_OUT_OF_DATA,
	DMERR_EXTRA_DATA,
	DMERR_BOUNDS,

	// PACK-file subsystem
	DMERR_NOTPACK,
	DMERR_VERSION,
	DMERR_INVALID,
	DMERR_COMPRESSION,
};


// Resource management defines
#define DMRES_NAME_LEN  32
#define DMRES_DATA_PACK	"data.pak"  // Name of the data-file
#define DMRES_DATA_PATH	"DATA/"     // Sub-directory path
#define DMRES_RES_FILE  "res.txt"   // Resource data file


// Mutexes
#define DMMutex SDL_mutex
#define dmCreateMutex() SDL_CreateMutex()
#define dmDestroyMutex(x) SDL_DestroyMutex(x)
#define dmMutexLock(x) SDL_mutexP(x)
#define dmMutexUnlock(x) SDL_mutexV(x)


/* Define a boolean type
 */
#if !defined(FALSE) && !defined(TRUE) && !defined(BOOL)
typedef enum { FALSE = 0, TRUE = 1 } BOOL;
#endif

#ifndef BOOL
#ifdef bool
#define BOOL bool
#else
#define BOOL int
#endif
#endif


/* Fixed point math type
 */
typedef union
{
    Uint64 dw;
    Uint32 w[2];
} DMFixedPoint;


typedef union
{
    Uint32 dw;
    Uint16 w[2];
} DMFixedPoint32;


/* Macros for fixed point math
 */
#if __GNUC__ >= 3
#  define FP_SET(a, k) a.dw = k ## ULL
#else
#  define FP_SET(a, k) a.dw = k
#endif

#define FP_CONV(a, k) a.dw = k

#ifndef SDL_BYTEORDER
#  error Undefined byteorder!
#endif

#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
#  define FP_SETH(a, k) a.w[0] = (k)
#  define FP_SETL(a, k) a.w[1] = (k)
#  define FP_SETHL(a, h, l) { a.w[0] = (h); a.w[1] = (l); }
#  define FP_GETH(a) a.w[0]
#  define FP_GETL(a) a.w[1]
#elif (SDL_BYTEORDER == SDL_LIL_ENDIAN)
#  define FP_SETH(a, k) a.w[1] = (k)
#  define FP_SETL(a, k) a.w[0] = (k)
#  define FP_SETHL(a, h, l) { a.w[1] = (h); a.w[0] = (l); }
#  define FP_GETH(a) a.w[1]
#  define FP_GETL(a) a.w[0]
#else
#  error Unsupported byte order!
#endif

#define FP_PRINTF(a)   printf("%.8x:%.8x", FP_GETH(a), FP_GETL(a))
#define FP_PRINTF32(a) printf("%.4x:%.4x", FP_GETH(a), FP_GETL(a))

#define FP_ADD(a, b) a.dw += b.dw
#define FP_SUB(a, b) a.dw -= b.dw
#define FP_ADD_R(r, a, b) r.dw = a.dw + b.dw
#define FP_SUB_R(r, a, b) r.dw = a.dw - b.dw
#define FP_DIV(a, b) a.dw /= b.dw
#define FP_MUL(a, b) a.dw *= b.dw
#define FP_DIV_R(r, a, b) r.dw = (a.dw / b.dw)
#define FP_MUL_R(r, a, b) r.dw = (a.dw * b.dw)


/* Miscellaneous types
 */
typedef struct
{
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
    Uint8 a,g,b,r;
#elif (SDL_BYTEORDER == SDL_LIL_ENDIAN)
    Uint8 r,g,b,a;
#endif
} DMRGBA32;


typedef float DMFloat;


/* Drawing modes used by blitting and some other functions.
 */
enum
{
    DMD_NONE        = 0x0000,
    DMD_TRANSPARENT = 0x0001,
    DMD_SATURATE    = 0x0002,
 
    DMD_ANTIALIAS   = 0x0004,
    
    DMD_NMODES      = 6
};


// Available bitdepths. Not all functions may support every one of these.
enum
{
    DMD_8BIT = 0,
    DMD_32BIT,
    
    DMD_NBITDEPTHS
};


static inline int dmBitsPerPixel2Index(int bpp)
{
    return (bpp == 8 ? 0 : (bpp == 32 ? 1 : -1));
}


/* Generic parameter interpolation
 */
#define DMM_S_CURVE(t)     ((t) * (t) * (3.0f - 2.0f * (t)))
#define DMM_LERP(t, a, b)  ((a) + (t) * ((b) - (a)))

typedef struct
{
    DMFloat start, end, nsteps;
} DMLerpContext;


void       dmLerpInit(DMLerpContext *ctx, DMFloat start, DMFloat end, DMFloat nsteps);
DMFloat    dmLerpSCurve(DMLerpContext *ctx, const DMFloat step);
DMFloat    dmLerp1(DMLerpContext *ctx, const DMFloat step);
DMFloat    dmCatmull_Rom(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3);


/* Perlin noise
 */
void       dmPerlinInit(void);
DMFloat    dmPerlinNoise2D(DMFloat x, DMFloat y, DMFloat alpha, DMFloat beta, int n);


/* TTF text drawing
 */
#ifdef DM_GFX_TTF_TEXT
void       dmDrawTTFTextConst(SDL_Surface *screen, TTF_Font *font, SDL_Color col, int x, int y, const char *fmt);
void       dmDrawTTFTextVA(SDL_Surface *screen, TTF_Font *font, SDL_Color col, int x, int y, const char *fmt, va_list ap);
void       dmDrawTTFText(SDL_Surface *screen, TTF_Font *font, SDL_Color col, int x, int y, const char *fmt, ...);
#endif

/* Arbitrary line drawing
 */
#ifdef DM_GFX_LINES
typedef int (*DMDrawLineFunc)(SDL_Surface *src, int x0, int y0, int x1, int y1, const Uint32 color);
DMDrawLineFunc dmGetDrawLineFunc(SDL_PixelFormat *dst, int mode);
int        dmDrawLineAny(SDL_Surface *src, int x0, int y0, int x1, int y1, const Uint32 color, int mode);
#endif

/* Scaled blitting functions
 */
#ifdef DM_GFX_BLITS
typedef int (*DMScaledBlitFunc)(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst);

DMScaledBlitFunc dmGetScaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode);
int dmScaledBlitSurfaceAny(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst, int mode);
#endif

/* Misc functions
 */
#ifdef DM_GFX_MISC
void       dmFillRect(SDL_Surface *screen, int x0, int y0, int x1, int y1, const Uint32 col);
void       dmDrawHLine(SDL_Surface *screen, int x0, int x1, int yc, const Uint32 col);
void       dmDrawVLine(SDL_Surface *screen, int y0, int y1, int xc, const Uint32 col);
void       dmDrawBox3D(SDL_Surface *screen, int x0, int y0, int x1, int y1, Uint32 bgcol, Uint32 ucol, Uint32 dcol);
void       dmClearSurface(SDL_Surface *screen, const Uint32 col);
Uint32     dmMapRGB(SDL_Surface *screen, int r, int g, int b);
Uint32     dmMapRGBA(SDL_Surface *screen, int r, int g, int b, int a);
int        dmDirectBlitSurface(SDL_Surface *bmp, SDL_Surface *screen);
#endif


/* Global variables
 */
extern char *dmProgName,
            *dmProgDesc,
            *dmProgVersion,
            *dmProgAuthor,
            *dmProgLicense;

extern int dmVerbosity;
void       dmInitProg(char *name, char *desc, char *version, char *author, char *license);
void       dmPrintBanner(FILE *outFile, const char *name, const char *usage);

void       dmMsgVA(int level, const char *fmt, va_list ap);
void       dmMsg(int level, const char *fmt, ...);
void       dmPrintVA(int level, const char *fmt, va_list ap);
void       dmPrint(int level, const char *fmt, ...);
void       dmErrorVA(const char *fmt, va_list);
void       dmError(const char *fmt, ...);

void *     dmMalloc(size_t);
void *     dmMalloc0(size_t);
void *     dmRealloc(void *, size_t);
void *     dmCalloc(size_t, size_t);
void       dmFree(void *);

BOOL dmGetIntVal(const char *s, int *i);

int         dmGetErrno();
const char *dmErrorStr(int error);

char *     dm_strdup(const char *);
char *     dm_strdup_vprintf(const char *, va_list);
char *     dm_strdup_printf(const char *, ...);


/* Endianess swapping macros
 */
#define DM_SWAP_16_LE_BE(value)    ((Uint16) (   \
    (Uint16) ((Uint16) (value) >> 8) |      \
    (Uint16) ((Uint16) (value) << 8)) )


#define DM_SWAP_32_LE_BE(value) ((Uint32) (               \
    (((Uint32) (value) & (Uint32) 0x000000ffU) << 24) | \
    (((Uint32) (value) & (Uint32) 0x0000ff00U) <<  8) | \
    (((Uint32) (value) & (Uint32) 0x00ff0000U) >>  8) | \
    (((Uint32) (value) & (Uint32) 0xff000000U) >> 24)))

#ifdef DM_HAVE_64BIT
#define DM_SWAP_64_LE_BE(value) ((Uint64) (                           \
    (((Uint64) (value) & (Uint64) 0x00000000000000ffULL) << 56) |   \
    (((Uint64) (value) & (Uint64) 0x000000000000ff00ULL) << 40) |   \
    (((Uint64) (value) & (Uint64) 0x0000000000ff0000ULL) << 24) |   \
    (((Uint64) (value) & (Uint64) 0x00000000ff000000ULL) <<  8) |   \
    (((Uint64) (value) & (Uint64) 0x000000ff00000000ULL) >>  8) |   \
    (((Uint64) (value) & (Uint64) 0x0000ff0000000000ULL) >> 24) |   \
    (((Uint64) (value) & (Uint64) 0x00ff000000000000ULL) >> 40) |   \
    (((Uint64) (value) & (Uint64) 0xff00000000000000ULL) >> 56)))
#endif

/* Macros that swap only when needed ...
 */
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
#    define DM_LE16_TO_NATIVE(value) DM_SWAP_16_LE_BE(value)
#    define DM_LE32_TO_NATIVE(value) DM_SWAP_32_LE_BE(value)
#    define DM_NATIVE_TO_LE16(value) DM_SWAP_16_LE_BE(value)
#    define DM_NATIVE_TO_LE32(value) DM_SWAP_32_LE_BE(value)

#    define DM_BE16_TO_NATIVE(value) ((Uint16) (value))
#    define DM_BE32_TO_NATIVE(value) ((Uint32) (value))
#    define DM_NATIVE_TO_BE16(value) ((Uint16) (value))
#    define DM_NATIVE_TO_BE32(value) ((Uint32) (value))

#    ifdef DM_HAVE_64BIT
#        define DM_LE64_TO_NATIVE(value) DM_SWAP_64_LE_BE(value)
#        define DM_NATIVE_TO_LE64(value) DM_SWAP_64_LE_BE(value)
#        define DM_BE64_TO_NATIVE(value) ((Uint64) (value))
#        define DM_NATIVE_TO_BE64(value) ((Uint64) (value))
#    endif

#elif (SDL_BYTEORDER == SDL_LIL_ENDIAN)

#    define DM_LE16_TO_NATIVE(value) ((Uint16) (value))
#    define DM_LE32_TO_NATIVE(value) ((Uint32) (value))
#    define DM_NATIVE_TO_LE16(value) ((Uint16) (value))
#    define DM_NATIVE_TO_LE32(value) ((Uint32) (value))

#    define DM_BE16_TO_NATIVE(value) DM_SWAP_16_LE_BE(value)
#    define DM_BE32_TO_NATIVE(value) DM_SWAP_32_LE_BE(value)
#    define DM_NATIVE_TO_BE16(value) DM_SWAP_16_LE_BE(value)
#    define DM_NATIVE_TO_BE32(value) DM_SWAP_32_LE_BE(value)

#    ifdef DM_HAVE_64BIT
#        define DM_LE64_TO_NATIVE(value) ((Uint64) (value))
#        define DM_NATIVE_TO_LE64(value) ((Uint64) (value))
#        define DM_BE64_TO_NATIVE(value) DM_SWAP_64_LE_BE(value)
#        define DM_NATIVE_TO_BE64(value) DM_SWAP_64_LE_BE(value)
#    endif
#endif


#ifdef __cplusplus
}
#endif
#endif // DMLIB_H