Mercurial > hg > dmlib
view src/dmlib.h @ 1785:86d10d5d4915
Fix case where DMGrowBuf is growing backwards and needs to be reallocated in
dmGrowBufRealloc() and the data is moved to the "end" of the newly grown
buffer. Previously we used clrsize as data size, but that is (in retrospect)
obviously incorrect. Use old buffer size instead.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 13 Jun 2018 01:39:06 +0300 |
parents | dcc48679a89e |
children | ca9fe688ab6b |
line wrap: on
line source
/* * DMLib * -- Main header file * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2011-2018 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 <SDL_render.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <ctype.h> #ifdef DM_USE_ASSERTS # include <assert.h> #else # define assert(NEXPR) // stub #endif // Check for arch bitness #if defined(__WIN64) || defined(_WIN64) || defined(_WIN32) || defined(__WIN32) # define DM_WINDOWS 1 # if defined(__MINGW32__) || defined(__MINGW64__) # define __USE_MINGW_ANSI_STDIO 1 # endif #endif #if !defined(DM_ARCH) # if defined(__LP64__) || defined(_LP64) # define DM_ARCH 64 # else # define DM_ARCH 32 # endif #endif #if !defined(DM_ARCH) && (defined(__WIN64) || defined(_WIN64)) # define DM_ARCH 64 #endif #if !defined(DM_ARCH) && (defined(__WIN32) || defined(_WIN32)) # define DM_ARCH 32 #endif // Do we have a valid arch? // If so, set some printf specifiers #if DM_ARCH == 32 # define DM_PRIu32 "u" # define DM_PRId32 "d" # define DM_PRIx32 "x" # ifdef DM_WINDOWS # define DM_PRIu64 "u" # define DM_PRId64 "d" # define DM_PRIx64 "x" # else # define DM_PRIu64 "llu" # define DM_PRId64 "lld" # define DM_PRIx64 "llx" # endif # define DM_PRIu_SIZE_T "u" # define DM_PRId_SSIZE_T "d" # define DM_PRIx_SIZE_T "x" #elif DM_ARCH == 64 # define DM_PRIu32 "u" # define DM_PRId32 "d" # define DM_PRIx32 "x" # define DM_PRIu64 "lu" # define DM_PRId64 "ld" # define DM_PRIx64 "lx" # define DM_PRIu_SIZE_T "lu" # define DM_PRId_SSIZE_T "ld" # define DM_PRIx_SIZE_T "lx" #else # error Could not determine architecture (32/64bit), please define DM_ARCH=32 or 64 #endif #ifdef __cplusplus extern "C" { #endif // Defaults #define DM_PROG_AUTHOR "By Matti 'ccr' Hamalainen (C) Copyright 2018 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_INTERNAL, 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_DATA_ERROR, // Data decoding/encoding/parsing error DMERR_VERSION, // Unsupported data version // PACK-file subsystem DMERR_NOTPACK, DMERR_PACK_VERSION, DMERR_INVALID, DMERR_COMPRESSION, }; // Directory/path separator stuff #define DM_DIR_SEPARATOR '/' // 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 types */ typedef union { Sint64 dw; Sint32 w[2]; } DMFixedPoint; typedef union { Sint32 dw; Sint16 w[2]; } DMFixedPoint32; /* Macros for fixed point math */ #define FP_SET(a, k) a.dw = k ## ULL #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 } DMColor; 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)); } 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)); } /* 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, const int dwidth, const int dheight); #define DM_HEADER #include "dmblitfunc.h" #undef DM_HEADER #endif // DM_GFX_BLITS 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, ...); int dmErrorVA(const int error, const char *fmt, va_list); int dmError(const int error, const char *fmt, ...); void dmErrorMsg(const char *fmt, ...); int dmGetErrno(); const char *dmErrorStr(const int error); #ifdef DM_DEBUG # define dmErrorDBG dmError # define dmErrorDBGMsg dmErrorMsg #else # define dmErrorDBG(ecode, fmt, ...) (ecode) // Dummy # define dmErrorDBGMsg(fmt, ...) #endif void * dmMalloc(size_t len); void * dmMalloc0(size_t len); void * dmRealloc(void *ptr, size_t len); void * dmCalloc(size_t n, size_t len); void dmFree(void *ptr); void dmFreeRReal(void **ptr); #define dmFreeR(ptr) dmFreeRReal((void **) ptr) #if defined(DM_HAVE_MEMSET) || defined(DM_HAVE_STRING_H) static inline void * dmMemset(void *ptr, const int c, size_t n) { return memset(ptr, c, n); } #else void * dmMemset(void *ptr, const int c, size_t n); #endif 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 *, ...); char * dm_basefilename(const char *filename); char * dm_strdup_fext(const char *filename, const char *fmt); char * dm_strrcasecmp(char *str, const char *needle); BOOL dmGetIntVal(const char *s, unsigned int *i); /* 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))) #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))) /* 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)) # 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)) #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) # 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 #ifdef __cplusplus } #endif #endif // DMLIB_H