/* Macros - Useful macros - Bryan Ford */
#ifndef BRY_MACROS_H
#define BRY_MACROS_H

#ifndef EXEC_LIBRARIES_H
#include <exec/libraries.h>
#endif

#ifndef memset

/* Builtin memory functions */
#define memset(to,c,n) __builtin_memset(to,c,n)
#define memcpy(to,fr,n) __builtin_memcpy(to,fr,n)
#define memcmp(a,b,n) __builtin_memcmp(a,b,n)

/* Prototypes for builtin memory functions */
void *__builtin_memset(void *to,void *c,int n);
void *__builtin_memcpy(void *to,void *fr,int n);
int __builtin_memcmp(void *a,void *b,int n);

#endif

#ifndef strlen

/* Builtin string functions */
#define strlen(str) __builtin_strlen(str)
#define strcpy(to,fr) __builtin_strcpy(to,fr)
#define strcmp(a,b) __builtin_strcmp(a,b)

/* Prototypes for builtin string functions */
int __builtin_strlen(char *str);
char *__builtin_strcpy(char *to,char *fr);
int __builtin_strcmp(char *a,char *b);

#endif

/* Simple math macros */
#ifndef abs
#ifndef __GNUC__
#define abs(a) ((a) >= 0 ? (a) : -(a))
#else
#define abs(a) ({int _a = (a); _a >= 0 ? _a : -_a; })
#endif
#endif

#ifndef min
#ifndef __GNUC__
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#else
#define min(a,b) ({int _a = (a), _b = (b); _a < _b ? _a : _b; })
#define max(a,b) ({int _a = (a), _b = (b); _a > _b ? _a : _b; })
#endif

#ifndef sign
#ifndef __GNUC__
#define sign(a) ((a) > 0 ? 1 : (a) < 0 ? -1 : 0)
#else
#define sign(a) ({int _a = (a); _a > 0 ? 1 : _a < 0 ? -1 : 0; })
#endif
#endif

#define choprange(v,low,hi) ((v) < (low) ? (low) : (v) > (hi) ? (hi) : (v))
#define chopzrange(v,hi) choprange(v,0,hi)

/* See if we're running in a 2.0 system or not */
#define Is20 (((struct Library*)SysBase)->lib_Version >= 36)

/* Process/task pointers */
#define TaskPtr ((struct Task*)FindTask(0L))
#define ProcPtr ((struct Process*)TaskPtr)

/* ChangeDir() CurrentDir()'s to a new directory and UnLock()'s the old one */
#define ChangeDir(lock) (UnLock(CurrentDir(lock)))

/* Mimics other Blt...() routines */
#define BltBitMapBitMap(fbm,fx,fy,tbm,tx,ty,w,h,minterm) BltBitMap(fbm,fx,fy,tbm,tx,ty,w,h,minterm,0xff,0)
#define BltRastPortRastPort(frp,fx,fy,trp,tx,ty,w,h,minterm) ClipBlit(frp,fx,fy,trp,tx,ty,w,h,minterm)

/* Mimics the global "custom" structure that was in Amiga.lib */
#define custom (*((struct Custom*)0xDFF000))

/* We don't want SetIoErr() anymore - use the new error system! */
#define SetIoErr(blah) obsolete! obsolete! obsolete! obsolete! obsolete!

/* Clear the BSS data for the program */
#define ClearBSS() \
  { extern long __far _BSSBAS[], __far _BSSLEN; \
    register long len = (long)(&_BSSLEN); register long *p = _BSSBAS; \
    do { *(p++) = 0; } while (--len); }

/* Display an error message in an Intuition alert (usually at the end of die()) */
#define AlertMes(progname,message) \
  if(message) \
    { \
    char alertbuf[200]; \
      memset(alertbuf,0,200); \
      memcpy(alertbuf,"\x00\x10\x19Press either mouse button to end program\x00\x01\x00\x10\x0d"progname" - Fatal Error: ",64+strlen(progname)); \
      strcpy(alertbuf+64+strlen(progname),message); \
      DisplayAlert(RECOVERY_ALERT,alertbuf,35); \
    }

/* Display a fixed error message in an Intuition alert */
#define AlertFixedMes(message) \
  DisplayAlert(RECOVERY_ALERT, \
  "\x00\x10\x19Press either mouse button to end program\x00\x01\x00\x10\x0d"message"\00",35);

/* For debuggin purposes */
#define illegal __builtin_emit(0x4afc);

/* Raw keycodes */
#define RawSpace        0x40
#define RawESC          0x45
#define RawDel          0x46
#define RawUp           0x4c
#define RawDown         0x4d
#define RawRight        0x4e
#define RawLeft         0x4f
#define RawF1           0x50
#define RawF2           0x51
#define RawF3           0x52
#define RawF4           0x53
#define RawF5           0x54
#define RawF6           0x55
#define RawF7           0x56
#define RawF8           0x57
#define RawF9           0x58
#define RawF10          0x59
#define RawHelp         0x5f

#endif
