
#ifndef SAVAGE_MACROS_H
#define SAVAGE_MACROS_H

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <dos/dosextens.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>

#include <setjmp.h>

/******************************************************************************
** these externs should be defined by the compiler or by the user! the makros
** below just use them
*/

#ifndef SysBase
extern struct Library *SysBase;
#endif

/******************************************************************************
** this lets you use simple exception handling with standard ansi-c
** note: never RAISE a value of zero (this would result into an infinite loop)
**
**      TRY
**      {
**           ... RAISE(5); ...
**      }
**      CATCH
**      {
**        switch (exception)
**        {
**          ...
**          case 5:  ...
**          ...
**        }
**      }
**      ENDTRY
*/

// #define TRY       { jmp_buf buf; int exception = setjmp(buf); if (!exception) {
// #define CATCH     } else {
// #define ENDTRY    } }
// #define RAISE(e)  longjmp(buf, e)

#define TRY          { int exception = 0;
#define CATCH        ____localcatchlabel: if (exception) {
#define ENDTRY       } }
#define RAISE(e)     exception = e; goto ____localcatchlabel;

/******************************************************************************
** other stuff
*/

#define MAX(a,b)                       (((a)>(b))?(a):(b))
#define MIN(a,b)                       (((a)<(b))?(a):(b))
#define BPTR2APTR(b)                   (((long)b)<<2)
#define APTR2BPTR(a)                   (((long)a)>>2)

/******************************************************************************
** these macros replace some savagelib functions :)
*/

#define sav_PutChar(a,v)               (*((char*)(a)))=((char)(v))
#define sav_PutInt(a,v)                (*((short*)(a)))=((short)(v))
#define sav_PutLong(a,v)               (*((long*)(a)))=((long)(v))
#define sav_GetChar(a)                 (*((char*)(a)))
#define sav_GetInt(a)                  (*((short*)(a)))
#define sav_GetLong(a)                 (*((long*)(a)))
#define sav_Beep()                     DisplayBeep(NULL)
#define sav_Even(n)                    (!((n)&1))
#define sav_BitAND(a,b)                ((a)&(b))
#define sav_BitOR(a,b)                 ((a)|(b))
#define sav_BitXOR(a,b)                ((a)^(b))
#define sav_BitNOT(a)                  (~(a))
#define sav_IsListEmpty(l)             ((((struct List *)(l))->lh_TailPred)==(struct Node *)(l))
#define sav_GetSucc(n)                 (((n)->ln_Succ->ln_Succ)?((n)->ln_Succ):NULL)
#define sav_GetPred(n)                 (((n)->ln_Pred->ln_Pred)?((n)->ln_Pred):NULL)
#define sav_FreeTotalMem()             AvailMem(MEMF_ANY)
#define sav_FreeChipMem()              AvailMem(MEMF_CHIP)
#define sav_FreeFastMem()              AvailMem(MEMF_FAST)
#define sav_FindCOS()                  Output()
#define sav_FindCIS()                  Input()
#define sav_KickVersion()              (((struct ExecBase *)SysBase)->LibNode.lib_Version)
#define sav_CurrentDir()               (((struct Process *) FindTask(NULL))->pr_CurrentDir)
#define sav_Write(s)                   Write(Output(),(s),strlen(s))
#define sav_MemFlush()                 AllocMem(0x7fffffff, MEMF_CHIP);AllocMem(0x7fffffff, MEMF_FAST);AllocMem(0x7fffffff, MEMF_ANY);
#define sav_GetFirstListNode(l)        (sav_IsListEmpty(l)?NULL:((l)->lh_Head))
#define sav_GetLastListNode(l)         (sav_IsListEmpty(l)?NULL:((l)->lh_TailPred))

#endif

