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