Mercurial > hg > dmlib
diff src/dmlib.h @ 812:1e5cf1144f36
Move library source under src/ subdirectory.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 16 May 2014 03:22:39 +0300 |
parents | dmlib.h@eba3b87f3f84 |
children | b0cd28b6c9f3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dmlib.h Fri May 16 03:22:39 2014 +0300 @@ -0,0 +1,509 @@ +/* + * DMLib + * -- Main header file + * Programmed and designed by Matti 'ccr' Hamalainen + * (C) Copyright 2011-2014 Tecnic Software productions (TNSP) + */ +#ifndef DMLIB_H +#define DMLIB_H + +#include <SDL_config.h> +#include <SDL_endian.h> +#include <SDL_types.h> +#include <SDL_mutex.h> +#include <SDL_thread.h> +#include <SDL_video.h> +#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' Hamalainen (C) Copyright 2014 TNSP" +#define DM_PROG_LICENSE "Et all, see README / COPYING for more information." + +/* Error codes + */ +enum { + // General error codes + DMERR_OK = 0, + DMERR_PROGRESS, // Status OK, but operation in progress + + DMERR_FOPEN, + DMERR_FREAD, + DMERR_FWRITE, + DMERR_FSEEK, + DMERR_NOT_FOUND, // Resource/data not found + + DMERR_INVALID_DATA, // Some data was invalid + DMERR_MALLOC, // Memory allocation failure + DMERR_ALREADY_INIT, // Resource has already been initialized + DMERR_INIT_FAIL, // General initialization failure + DMERR_INVALID_ARGS, + + DMERR_NULLPTR, // NULL pointer specified in critical argument + DMERR_NOT_SUPPORTED,// Operation not supported + DMERR_OUT_OF_DATA, + DMERR_EXTRA_DATA, + DMERR_BOUNDS, + + DMERR_INTERNAL, + + // 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 + + +/* 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 + + +/* Math constants + */ +#define DM_PI 3.14159265358f +#define DM_PI2 6.28318530718f +#define DM_E 2.71828182846f + + +/* Fixed point math type + */ +typedef union +{ + Sint64 dw; + Sint32 w[2]; +} DMFixedPoint; + + +typedef union +{ + Sint32 dw; + Sint16 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_GETH32(a) a.w[0] +# define FP_GETL32(a) a.w[1] +# define FP_GETH16(a) a.w[0] +# define FP_GETL16(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_GETH32(a) a.w[1] +# define FP_GETL32(a) a.w[0] +# define FP_GETH16(a) a.w[1] +# define FP_GETL16(a) a.w[0] +#else +# error Unsupported byte order! +#endif + +#define FP_PRINTF64(a) printf("%.8x:%.8x", FP_GETH32(a), FP_GETL32(a)) +#define FP_PRINTF32(a) printf("%.4x:%.4x", FP_GETH16(a), FP_GETL16(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; + + +// Macro for swapping two lvalues of same type +#define DM_SWAP(T, A, B) { if ((B) < (A)) { T swtmp = (B); B = (A); A = swtmp; } } + + +/* 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 dmCatmullRom(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3); + + +static inline DMFloat dmClamp10(const DMFloat a) +{ + return (a < 0.0f ? 0.0f : (a > 1.0f ? 1.0f : a)); +} + + +static inline int dmClamp(const int v, const int min, const int max) +{ + return (v < min ? min : (v > max ? max : v)); +} + + +static inline DMFloat dmLerpSCurve(DMLerpContext *ctx, const DMFloat step) +{ + const DMFloat n = step / ctx->nsteps; + const DMFloat v = DMM_S_CURVE(n); + return DMM_LERP(v, ctx->start, ctx->end); +} + + +static inline DMFloat dmLerpSCurveClamp(DMLerpContext *ctx, const DMFloat step) +{ + const DMFloat n = dmClamp10(step / ctx->nsteps); + const DMFloat v = DMM_S_CURVE(n); + return DMM_LERP(v, ctx->start, ctx->end); +} + + +static inline DMFloat dmLerp1(DMLerpContext *ctx, const DMFloat step) +{ + const DMFloat v = step / ctx->nsteps; + return DMM_LERP(v, ctx->start, ctx->end); +} + + +static inline DMFloat dmLerp1Clamp(DMLerpContext *ctx, const DMFloat step) +{ + const DMFloat v = dmClamp10(step / ctx->nsteps); + return DMM_LERP(v, ctx->start, ctx->end); +} + + +static inline DMFloat dmCatmullRomClamp(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3) +{ + return dmCatmullRom(dmClamp10(t), p0, p1, p2, p3); +} + + +/* Perlin noise + */ +void dmPerlinInit(void); +DMFloat dmPerlinNoise2D(DMFloat x, DMFloat y, DMFloat alpha, DMFloat beta, int n); + + +/* Arbitrary line drawing + */ +#ifdef DM_GFX_LINES +#define DM_HEADER +#include "dmlinefunc.h" + +enum +{ + CLIP_TOP = 1, + CLIP_BOTTOM = 2, + CLIP_RIGHT = 4, + CLIP_LEFT = 8 +}; + +#define DM_CLIP_FUNC dmClipLineCoordsFloat +#define DM_COORD_TYPE DMFloat +#include "dmlineclip.h" + +#undef DM_HEADER +#endif + + +/* Various 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); + +typedef int (*DMUnscaledBlitFunc)(SDL_Surface *src, const int x0, const int y0, SDL_Surface *dst); +DMUnscaledBlitFunc dmGetUnscaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode); +int dmUnscaledBlitSurfaceAny(SDL_Surface *src, const int x0, const int y0, SDL_Surface *dst, int mode); + +SDL_Surface *dmConvertScaledSurface(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags, const int dwidth, const int dheight); + + +#define DM_HEADER +#include "dmblitfunc.h" +#undef DM_HEADER + +#endif // DM_GFX_BLITS + + +/* 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 ucol, Uint32 dcol); +void dmFillBox3D(SDL_Surface *screen, int x0, int y0, int x1, int y1, Uint32 bgcol, Uint32 ucol, Uint32 dcol); + +#endif // DM_GFX_MISC + + +static inline void dmClearSurface(SDL_Surface *screen, const Uint32 col) +{ + SDL_FillRect(screen, NULL, col); +} + + +static inline Uint32 dmMapRGB(SDL_Surface *screen, int r, int g, int b) +{ + return SDL_MapRGB(screen->format, r, g, b); +} + + +static inline Uint32 dmMapRGBA(SDL_Surface *screen, int r, int g, int b, int a) +{ + return SDL_MapRGBA(screen->format, r, g, b, a); +} + + +static inline int dmDirectBlitSurface(SDL_Surface *bmp, SDL_Surface *screen) +{ + return SDL_BlitSurface(bmp, NULL, screen, NULL); +} + + +static inline SDL_Surface *dmCopySurface(SDL_Surface *src) +{ + if (src != NULL) + return SDL_ConvertSurface(src, src->format, src->flags); + else + return NULL; +} + + +/* 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_strndup(const char *, const size_t n); +char * dm_strdup_vprintf(const char *, va_list); +char * dm_strdup_printf(const char *, ...); + + +/* Mutexes + */ +#ifdef DM_MUTEX_DEBUG + +typedef struct +{ + BOOL used; + Uint32 id; + int state; +} DMMutexLock; + +typedef struct +{ + char *cr_file; + int cr_line; + SDL_mutex *m; + DMMutexLock locks[8]; +} DMMutex; + +#define dmMutexLock(x) dmDOMutexLock(x, __FILE__, (int) __LINE__) +#define dmMutexUnlock(x) dmDOMutexUnlock(x, __FILE__, (int) __LINE__) +#define dmCreateMutex(x) dmDOCreateMutex(__FILE__, (int) __LINE__) + +int dmDOMutexLock(DMMutex *mutex, const char *file, const int line); +int dmDOMutexUnlock(DMMutex *mutex, const char *file, const int line); +DMMutex * dmDOCreateMutex(const char *file, const int line); +void dmDestroyMutex(DMMutex *mutex); + +#else +#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) +#endif + +/* 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