#ifndef _MNUDLL_H_
#define _MNUDLL_H_

#define SND_DefinePointer0(FunctionName,ret)	    \
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(void);       \
    ret (DLLCALL *DLLpfn_##FunctionName)(void)=NULL;	\
	ret DLLCALL FunctionName(void)							\
	{												\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)();		\
	}												\
	ret DLLCALL Fake##FunctionName(void)					\
	{												\
		ret fake=(ret)0;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@0";		


#define SND_DefinePointer1(FunctionName,ret,typ1)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1);       \
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1)=NULL;			\
	ret DLLCALL FunctionName(typ1 par1)						\
	{												\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1);			\
	}												\
	ret DLLCALL Fake##FunctionName(typ1 par1)					\
	{												\
		ret fake=(ret)0;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@4";
 

#define SND_DefinePointer1_def(FunctionName,ret,typ1,def_ret)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1);       \
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1)=NULL;			\
	ret DLLCALL FunctionName(typ1 par1)						\
	{												\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1);			\
	}												\
	ret DLLCALL Fake##FunctionName(typ1 par1)					\
	{												\
		ret fake=def_ret;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@4";
 

#define SND_DefinePointer2(FunctionName,ret,typ1,typ2) \
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2);      \
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2)=NULL;				\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2)				\
	{													\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return((*DLLpfn_##FunctionName)(par1,par2));			\
	}													\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2)					\
	{												\
		ret fake=(ret)0;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@8";

#define SND_DefinePointer3(FunctionName,ret,typ1,typ2,typ3)		\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3);				\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3)=NULL;							\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3)					\
	{																\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1,par2,par3);				\
	}																\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3)					\
	{												\
		ret fake=(ret)0;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@12";

#define SND_DefinePointer3_def(FunctionName,ret,typ1,typ2,typ3,def_ret)		\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3);				\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3)=NULL;							\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3)					\
	{																\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1,par2,par3);				\
	}																\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3)					\
	{												\
		ret fake=def_ret;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@12";

#define SND_DefinePointer4(FunctionName,ret,typ1,typ2,typ3,typ4)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4);		\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4)=NULL;							\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4)		\
	{																\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1,par2,par3,par4);			\
	}																\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4)					\
	{												\
		ret fake=(ret)0;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@16";

#define SND_DefinePointer4_def(FunctionName,ret,typ1,typ2,typ3,typ4,def_ret)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4);		\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4)=NULL;							\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4)		\
	{																\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1,par2,par3,par4);			\
	}																\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4)					\
	{												\
		ret fake=def_ret;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@16";

#define SND_DefinePointer5(FunctionName,ret,typ1,typ2,typ3,typ4,typ5)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5);		\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5)=NULL;								\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5  par5)\
	{																	\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1,par2,par3,par4,par5);			\
	}																	\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5  par5)					\
	{												\
		ret fake=(ret)0;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@20";

#define SND_DefinePointer5_def(FunctionName,ret,typ1,typ2,typ3,typ4,typ5,def_ret)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5);		\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5)=NULL;								\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5  par5)\
	{																	\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1,par2,par3,par4,par5);			\
	}																	\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5  par5)					\
	{												\
		ret fake=def_ret;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@20";

#define SND_DefinePointer7(FunctionName,ret,typ1,typ2,typ3,typ4,typ5,typ6,typ7)			\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5,typ6,typ7);					\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5,typ6,typ7)=NULL;													\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5 par5,typ6 par6,typ7 par7)	\
	{																						\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		return (*DLLpfn_##FunctionName)(par1,par2,par3,par4,par5,par6,par7);					\
	}																						\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5 par5,typ6 par6,typ7 par7)					\
	{												\
		ret fake=(ret)0;									\
		return fake;								\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@28";


#define SND_DefinePointer_void0(FunctionName,ret)	    \
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(void);       \
    ret (DLLCALL *DLLpfn_##FunctionName)(void)=NULL;	\
	ret DLLCALL FunctionName(void)							\
	{												\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		(*DLLpfn_##FunctionName)();		\
	}												\
	ret DLLCALL Fake##FunctionName(void)				\
	{												\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@0";

#define SND_DefinePointer_void1(FunctionName,ret,typ1)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1);       \
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1)=NULL;			\
	ret DLLCALL FunctionName(typ1 par1)						\
	{												\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		(*DLLpfn_##FunctionName)(par1);			\
	}												\
	ret DLLCALL Fake##FunctionName(typ1 par1)				\
	{												\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@4";
 

#define SND_DefinePointer_void2(FunctionName,ret,typ1,typ2) \
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2);      \
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2)=NULL;				\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2)				\
	{													\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		(*DLLpfn_##FunctionName)(par1,par2);			\
	}													\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2)				\
	{												\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@8";

#define SND_DefinePointer_void3(FunctionName,ret,typ1,typ2,typ3)		\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3);				\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3)=NULL;							\
    ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3)					\
	{																\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		(*DLLpfn_##FunctionName)(par1,par2,par3);				\
	}																\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3)				\
	{												\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@12";

#define SND_DefinePointer_void4(FunctionName,ret,typ1,typ2,typ3,typ4)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4);		\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4)=NULL;							\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4)		\
	{																\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		(*DLLpfn_##FunctionName)(par1,par2,par3,par4);			\
	}																\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4)				\
	{												\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@16";

#define SND_DefinePointer_void5(FunctionName,ret,typ1,typ2,typ3,typ4,typ5)	\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5);		\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5)=NULL;								\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5  par5)\
	{																	\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		(*DLLpfn_##FunctionName)(par1,par2,par3,par4,par5);			\
	}																	\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5  par5)				\
	{												\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@20";

#define SND_DefinePointer_void7(FunctionName,ret,typ1,typ2,typ3,typ4,typ5,typ6,typ7)			\
    typedef ret (DLLCALL *DLLtdpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5,typ6,typ7);					\
    ret (DLLCALL *DLLpfn_##FunctionName)(typ1,typ2,typ3,typ4,typ5,typ6,typ7)=NULL;													\
	ret DLLCALL FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5 par5,typ6 par6,typ7 par7)	\
	{																						\
		if (!DLLpfn_##FunctionName) DebugBreak();	\
		(*DLLpfn_##FunctionName)(par1,par2,par3,par4,par5,par6,par7);					\
	}																						\
	ret DLLCALL Fake##FunctionName(typ1 par1,typ2 par2,typ3 par3,typ4 par4,typ5 par5,typ6 par6,typ7 par7)				\
	{												\
	}												\
	char cz##FunctionName##[] = "_" #FunctionName "@28";


#define DLL_M_GetProcAddress(FunctionName,module)													\
	DLLpfn_##FunctionName=(DLLtdpfn_##FunctionName)GetProcAddress(module,#FunctionName);
#define DLL_M_GetProcAddressDecored(FunctionName,module)													\
	DLLpfn_##FunctionName=(DLLtdpfn_##FunctionName)GetProcAddress(module,cz##FunctionName);

#endif _MNUDLL_H_
