/*=========================================================================
* Macros.h :       The macros used by the project.
*
* Version                      1.0
* Creation date        09/08/96
* Revision date
*
* That file needs to be compatible for all platforms.
*
* (c) Ubi Studios 1996
*=======================================================================*/
 
#ifndef __MACROS_H__
#define __MACROS_H__
 
/******************************************/
#if _MSC_VER >= 1000
#pragma once
#endif /* _MSC_VER >= 1000 */
/******************************************/
 
#include "GAM/Options/EnumCsts.h"
 
/*
 * if the constants are not to be enumerated, the typedef does not
 * exist, enabling the programmer to choose the memory usage for the
 * variable. it is his responsibility to ensure that the scope is enough
 * for the enum range. the enumerated type is faked with the specified
 * type.
 * if the constants are enumerated, the type exists, and the variables
 * are of this type. the problem is that the memory usage is implementation-
 * dependant
 */
#if defined(D_EnumerateConstants)
 
#define M_BeginDeclareEnumerate(tdeWhatever)     \
typedef enum tdeWhatever##_                      \
{
 
#define M_EndDeclareEnumerate(tdeWhatever, type) \
} tdeWhatever;
 
#else /* D_EnumerateConstants */
 
#define M_BeginDeclareEnumerate(tdeWhatever)     \
enum                                             \
{
 
#define M_EndDeclareEnumerate(tdeWhatever, type) \
};                                               \
typedef type tdeWhatever;
 
#endif /* !D_EnumerateConstants */
 
/***************************************/
/**** Error macros (using ACPerror) ****/
/***************************************/
#define M_GameFatalError(ErrorNum) \
{ \
 if (ErrorNum>E_uwGameFatalErr&&ErrorNum<E_uwGameStartOfWarning) \
 { \
  Erm_M_ClearLastError(C_ucErmDefaultChannel);\
  Erm_M_UpdateLastError(Game,C_ucErmDefaultChannel,(unsigned short)ErrorNum,C_lErmNoDebugData,C_ucErmOpenInfoWindow,C_ucAllowStopForDebug, NULL);\
 } \
 else \
 { \
  Erm_M_ClearLastError((unsigned short)C_ucErmDefaultChannel);\
  Erm_M_UpdateLastError(Game,C_ucErmDefaultChannel,(unsigned short)E_uwGameFatalErrorNotAFatalError,C_lErmNoDebugData,C_ucErmOpenInfoWindow,C_ucAllowStopForDebug, NULL);\
 } \
}
 
#define M_GameInformationError(ErrorNum) \
{ \
 if (ErrorNum>E_uwGameStartOfInformationWarning&&ErrorNum<E_uwGameErrNumber) \
 { \
  Erm_M_UpdateLastError(Game,C_ucErmDefaultChannel,(unsigned short)ErrorNum,C_lErmNoDebugData,C_ucErmNoOpenInfoWindow,C_ucNeverStopForDebug, NULL);\
  Erm_M_ClearLastError(C_ucErmDefaultChannel);\
 } \
 else \
 { \
  M_GameFatalError(E_uwGameInformationErrorIsNotAInformationError); \
 } \
}
 
#define M_GameWarningError(ErrorNum) \
{ \
 if (ErrorNum>E_uwGameStartOfWarning&&ErrorNum<E_uwGameStartOfInformationWarning) \
 { \
  Erm_M_UpdateLastError(Game,C_ucErmDefaultChannel,(unsigned short)ErrorNum,C_lErmNoDebugData,C_ucErmOpenInfoWindow,C_ucAllowStopForDebug, NULL);\
 } \
 else \
 { \
  M_GameFatalError(E_uwGameWarningErrorIsNotAWarningError); \
 } \
}
 
#define M_GameInformationErrorWithString(ErrorNum,szString) \
{ \
 if (ErrorNum>E_uwGameStartOfInformationWarning&&ErrorNum<E_uwGameErrNumber) \
 { \
  Erm_M_UpdateLastError(Game,C_ucErmDefaultChannel,(unsigned short)ErrorNum,C_lErmNoDebugData,C_ucErmNoOpenInfoWindow,C_ucNeverStopForDebug, szString);\
  Erm_M_ClearLastError(C_ucErmDefaultChannel);\
 } \
 else \
 { \
  M_GameFatalError(E_uwGameInformationErrorIsNotAInformationError); \
 } \
}
 
/*******************************/
/**** Engine general macros ****/
/*******************************/
 
/*************************/
/**** Object's macros ****/
/*************************/
#define M_VoidMiniStructurePointer(p_stObject,i) (*(((void **)(p_stObject))+i))
#define M_ForAllMiniStructure(i) for (i=0;i<sizeof(tdstEngineObject)/sizeof(void*);i++)
#define M_ForAllMiniStructureExceptNULL(p_stObject,i) \
  M_ForAllMiniStructure(i) \
   if (M_VoidMiniStructurePointer(p_stObject,i)!=NULL)
#define M_ForAllMiniStructureNULL(p_stObject,i) \
  M_ForAllMiniStructure(i) \
   if (M_VoidMiniStructurePointer(p_stObject,i)==NULL)
 
#define M_CopyMSPointer(p_stDest,p_stSrc,ucRank) { M_VoidMiniStructurePointer((p_stDest),(ucRank)) = M_VoidMiniStructurePointer((p_stSrc),(ucRank)); }
 
/******************************/
/**** Engine Object Macros ****/
/******************************/
#define M_ObjectGetFamilyType(p_stObject) fn_otStandardGameGetFamilyType((p_stObject)->h_StandardGame)
#define M_ObjectGetModelType(p_stObject) fn_otStandardGameGetModelType((p_stObject)->h_StandardGame)
#define M_ObjectGetPersonalType(p_stObject) fn_otStandardGameGetPersonalType((p_stObject)->h_StandardGame)
#define M_ObjectSetFamilyType(p_stObject,Type) fn_vStandardGameSetFamilyType((p_stObject)->h_StandardGame,(Type))
#define M_ObjectSetModelType(p_stObject,Type) fn_vStandardGameSetModelType((p_stObject)->h_StandardGame,(Type))
#define M_ObjectSetPersonalType(p_stObject,Type) fn_vStandardGameSetPersonalType((p_stObject)->h_StandardGame,(Type))
 
#define M_ObjectIsActivable(p_stObject) (fn_bf1StandardGameGetIsActivable((p_stObject)->h_StandardGame)==1)
 
#define M_ObjectIsActive(p_stObject) (fn_bf1StandardGameGetIsActive((p_stObject)->h_StandardGame)==1)
#define M_ActivateObject(p_stObject) (fn_vStandardGameSetIsActive((p_stObject)->h_StandardGame,1))
#define M_UnactivateObject(p_stObject) (fn_vStandardGameSetIsActive((p_stObject)->h_StandardGame,0))
 
#define M_ObjectIsAlreadyTreated(p_stObject) (fn_ulStandardGameGetLastTrame((p_stObject)->h_StandardGame)==g_stEngineStructure.stEngineTimer.ulTrameNumber)
#define M_TreatObject(p_stObject) fn_vStandardGameSetLastTrame((p_stObject)->h_StandardGame,g_stEngineStructure.stEngineTimer.ulTrameNumber)
 
#define M_GetMSHandle(p_stSuperObject,Name) ((MS_tdxHandleTo##Name) ((struct tdstEngineObject_ *)(HIE_fn_hGetSuperObjectObject(p_stSuperObject)))->h_##Name)
#define M_GetEngineObject(p_stSuperObject) ((HIE_fn_ulGetSuperObjectType(p_stSuperObject) != HIE_C_ulActor)?NULL:((struct tdstEngineObject_ *)(HIE_fn_hGetSuperObjectObject(p_stSuperObject))))
#define M_SetSuperObject(p_stObject,p_stSuperObjectIn) fn_vStandardGameSetSuperObject((p_stObject)->h_StandardGame,(p_stSuperObjectIn))
#define M_GetSuperObject(p_stObject) (fn_h_StandardGameGetSuperObject((p_stObject)->h_StandardGame))
 
/*******************************************************/
#define	GAM_M_MakeSubMapNumber(_lSubMap,_lEntry)	( ( ( (_lSubMap)   & 0x0000FFFF ) << 16 ) + ( (_lEntry) & 0x0000FFFF ) )
#define GAM_M_GetSubMap(_lAbsolute)					( ( (_lAbsolute) & 0xFFFF0000 ) >> 16 )
#define GAM_M_GetEntry(_lAbsolute)					( (_lAbsolute)   & 0x0000FFFF )
/*******************************************************/
 
#endif /* __MACROS_H__ */
