/*************************************************************/
/* Includes and other common stuff for the MUI demo programs */
/*************************************************************/

/* MUI */
#include <libraries/mui.h>

/* System */
#include <inline/stubs.h>
#include <dos/dos.h>
#include <graphics/gfxmacros.h>
#include <workbench/workbench.h>

/* Prototypes */
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/icon_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/muimaster_protos.h>
#include <clib/asl_protos.h>

/* ANSI C */
#include <stdlib.h>
#include <string.h>

#ifndef __GNUC__
#include <stdio.h>
#endif

/* Compiler specific stuff */

#ifdef _DCC

#define REG(x) __ ## x
#define ASM
#define SAVEDS __geta4

#endif

#ifdef __GNUC__

/* these need some more work */
#define REG(x)
#define ASM
#define SAVEDS

/* for normal and base-relative programs */

extern void hookEntry(void);		/* Assembler stub that saves the registers (a0,a2,a1) on the stack */
extern void hookEntrya1a2(void);	/* Assembler stub that saves the registers (a2,a1) on the stack */

/* for resident programs (does not function yet due to a bug in gcc) */

extern void hookEntryRes(void);		/* Assembler stub that saves the registers (a0,a2,a1) on the stack (resident only) */
extern void hookEntryResa1a2(void);	/* Assembler stub that saves the registers (a2,a1) on the stack (resident only) */

ULONG aska4(void);					/* return current a4 */

#else

#define REG(x) register __ ## x
#define ASM    __asm
#define SAVEDS __saveds

#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/muimaster_pragmas.h>
#include <pragmas/asl_pragmas.h>

extern struct Library *IntuitionBase,*UtilityBase,*GfxBase,*DOSBase,*IconBase;

#endif

#ifdef __GNUC__
#include <inline/mui_master.h>
struct Library *IntuitionBase;
/* struct Library *UtilityBase, *GfxBase,*IconBase; */
#endif

struct Library *MUIMasterBase;



/*************************/
/* Init & Fail Functions */
/*************************/

static VOID fail(APTR app,char *str)
{
	if (app)
		MUI_DisposeObject(app);

#ifndef _DCC
	if (MUIMasterBase)
		CloseLibrary(MUIMasterBase);
#endif

#ifdef __GNUC__
	if(IntuitionBase) CloseLibrary(IntuitionBase);
/*	if(UtilityBase) CloseLibrary(UtilityBase);
	if(GfxBase) CloseLibrary(GfxBase);
	if(IconBase) CloseLibrary(IconBase); */

	if (str)
	{
		PutStr(str);
		PutStr("\n");
	}
#else
	if (str)
	{
		puts(str);
		exit(20);
	}
#endif

	exit(0);
}


#ifdef _DCC

int brkfunc(void) { return(0); }

int wbmain(struct WBStartup *wb_startup)
{
	extern int main(int argc, char *argv[]);
	return (main(0, NULL));
}

#endif


#ifdef __SASC
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
#endif


static VOID init(VOID)
{
#ifdef _DCC
	onbreak(brkfunc);
#endif

#ifndef _DCC
	if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN)))
		fail(NULL,"Failed to open "MUIMASTER_NAME".");
#endif

	if (!(IntuitionBase = OpenLibrary("intuition.library",37)))
		fail(NULL,"Failed to open intuition.library.");

}


#ifndef __SASC
static VOID stccpy(char *dest,char *source,int len)
{
	strncpy(dest,source,len);
	dest[len-1]='\0';
}
#endif


#ifndef MAKE_ID
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#endif

#ifndef __GNUC__
LONG __stack = 8192;
#endif
