reman3/Rayman_X/cpa/public/SCR/SCR_DyAr.h

483 lines
14 KiB
C

/*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
* SCR_DyAr.h
* Scripts, Beaudet Christophe
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
*/
#ifndef __SCR_DyAr_h__Types
#define __SCR_DyAr_h__Types
#ifndef __Only_Types__
#define __SCR_DyAr_h__Undef
#define __Only_Types__
#endif /* !__Only_Types__ */
/*
*=================================================================================================
* Includes.
*=================================================================================================
*/
#ifdef __SCR_DyAr_h__Undef
#undef __Only_Types__
#undef __SCR_DyAr_h__Undef
#endif /* __SCR_DyAr_h__Undef */
/*
*=================================================================================================
* Constants.
*=================================================================================================
*/
/*
* To export code.
*/
#undef CPA_EXPORT
#if defined(CPA_WANTS_IMPORT)
#define CPA_EXPORT __declspec(dllimport)
#elif defined(CPA_WANTS_EXPORT)
#define CPA_EXPORT __declspec(dllexport)
#else /* CPA_WANTS_IMPORT */
#define CPA_EXPORT
#endif /* CPA_WANTS_IMPORT */
/*
* Base allocation (and reallocation) of a dynamic array
*/
#define SCR_C_ui_DyAr_BaseForAllocation 100
/*
*=================================================================================================
* Types.
*=================================================================================================
*/
/*
* Header of a dynamic element.
*/
typedef struct SCR_tdst_DyAr_Header_
{
#ifdef SCR_DM_ProtectedVersion
unsigned int uiSizeOf; /* Size of this structure for test in debug mod */
#endif /* SCR_DM_ProtectedVersion */
unsigned int uiIndexInArray; /* Index in dynamic array */
unsigned char ucMemLevel; /* Memory level */
} SCR_tdst_DyAr_Header;
/*
* State of an element.
*/
typedef enum SCR_tde_DyAr_State
{
SCR_EDAS_DyAr_Invalid = 0, /* Invalid entry : Error */
SCR_EDAS_DyAr_Free, /* Entry free */
SCR_EDAS_DyAr_Occupy, /* Entry occupy */
} SCR_tde_DyAr_State;
/*
* Structure that describes an element of a dynamic array.
*/
typedef struct SCR_tdst_DyAr_Element_
{
void *d_vElement; /* Real element */
SCR_tde_DyAr_State eState; /* State of the element */
} SCR_tdst_DyAr_Element;
/*
* Structure that describes the dynamic array
*/
typedef struct SCR_tdst_DyAr_Description_
{
SCR_tdst_DyAr_Element *d_stDynArray; /* Address of dynamic array */
unsigned int uiNumValues; /* Number of values in array */
unsigned int uiMaxValues; /* Max number of values in array */
} SCR_tdst_DyAr_Description;
#endif /* !__SCR_DyAr_h__Types */
/*
*=================================================================================================
* Macros.
*=================================================================================================
*/
#if !defined(__SCR_DyAr_h__Macros) && !defined(__Only_Types__)
#define __SCR_DyAr_h__Macros
/*
* To add a new element of a specific type in a dynamic array.
* _Cast : Cast of structure to add.
* _Pos : To receive position of new allocated structure in dynamic array.
* _Pointer : To receive address of new allocated structure.
* _Array : Array concerned.
* _InitMem : Must reset memory allocation ?
*
* ALLOCATION IS IN BLOCK 0 FOR STATIC ELEMENTS.
*/
#define SCR_M_DyAr_AddElementStatic(_Cast, _Pos, _Pointer, _Array)\
{\
/*
* Allocate a place in dynamic array.
*/\
fn_v_Mem_SetMode(0);\
_Pos = fn_ui_DyAr_AllocateElement(&_Array, 1);\
/*
* Allocate a new structure if it's not already here.
*/\
/* Init current memory level of element */\
if((_Array).d_stDynArray[_Pos].d_vElement == NULL)\
{\
fn_v_Mem_SetMode(0);\
SCR_M_Mem_AllocAndSet(_Cast, _Pointer, 1);\
/*
* Initialize context in array.
*/\
(_Array).d_stDynArray[_Pos].d_vElement = _Pointer;\
SCR_M_Dbg_UpdateSizeOf_P(_Cast, _Pointer);\
}\
/*
* We initialize _Pointer with already allocated structure.
*/\
else\
{\
_Pointer = (_Cast *) (_Array).d_stDynArray[_Pos].d_vElement;\
SCR_M_Dbg_AssertStruct_P(_Cast, _Pointer);\
}\
/*
* It is now occupy...
*/\
(_Pointer)->stHeader.uiIndexInArray = _Pos;\
(_Pointer)->stHeader.ucMemLevel = 0;\
(_Array).d_stDynArray[_Pos].eState = SCR_EDAS_DyAr_Occupy;\
}
#define SCR_M_DyAr_AddElement(_Cast, _Pos, _Pointer, _Array)\
{\
/*
* Allocate a place in dynamic array.
*/\
fn_v_Mem_SetMode(0);\
_Pos = fn_ui_DyAr_AllocateElement(&_Array, 0);\
/*
* Allocate a new structure.
* Allocation depend on current memory level.
*/\
fn_v_Mem_SetMode(g_uc_Mem_CurrentMemLevel);\
SCR_M_Mem_Alloc(_Cast, _Pointer, 1);\
/*
* Initialize context in array.
*/\
(_Array).d_stDynArray[_Pos].d_vElement = (_Pointer);\
SCR_M_Dbg_UpdateSizeOf_P(_Cast, _Pointer);\
/*
* It is now occupy...
*/\
(_Pointer)->stHeader.uiIndexInArray = _Pos;\
(_Pointer)->stHeader.ucMemLevel = g_uc_Mem_CurrentMemLevel;\
(_Array).d_stDynArray[_Pos].eState = SCR_EDAS_DyAr_Occupy;\
}
#define SCR_M_DyAr_AddElementNoAlloc(_Pos, _Pointer, _Array)\
{\
/*
* Allocate a place in dynamic array.
*/\
fn_v_Mem_SetMode(0);\
_Pos = fn_ui_DyAr_AllocateElement(&_Array, 0);\
/*
* Initialize context in array.
*/\
(_Array).d_stDynArray[_Pos].d_vElement = (_Pointer);\
/*
* It is now occupy...
*/\
(_Pointer)->stHeader.uiIndexInArray = _Pos;\
(_Array).d_stDynArray[_Pos].eState = SCR_EDAS_DyAr_Occupy;\
}
/*
* To delete an element.
* _Cast : Cast of an element in array.
* _Pos : Position of element to delete.
* _Array : Array to delete the element.
* _Code : Code to free inside the element.
*/
#define SCR_M_DyAr_DeleteElement(_Cast, _Pos, _Array, _Code)\
{\
SCR_tdst_DyAr_Element *_p_stElement_;\
_Cast *_p_stPointer_;\
unsigned int _uiDPos_ = _Pos;\
/*
* Mark the element to be free.
*/\
_p_stElement_ = &(_Array)->d_stDynArray[_uiDPos_];\
_p_stElement_->eState = SCR_EDAS_DyAr_Free;\
_p_stPointer_ = (_Cast *) _p_stElement_->d_vElement;\
/*
* Really delete element if we can.
*/\
{_Code}\
fn_v_Mem_SetMode(_p_stPointer_->stHeader.ucMemLevel);\
SCR_M_Mem_Free(_p_stElement_->d_vElement);\
/*
* Reduce num of values if we delete last one.
*/\
if(_uiDPos_ == (_Array)->uiNumValues - 1)\
(_Array)->uiNumValues--;\
}
#define SCR_M_DyAr_DeleteElementNoAlloc(_Pos, _Array, _Code)\
{\
SCR_tdst_DyAr_Element *_p_stElement_;\
unsigned int _uiDPos_ = _Pos;\
/*
* Mark the element to be free.
*/\
_p_stElement_ = &(_Array)->d_stDynArray[_uiDPos_];\
_p_stElement_->eState = SCR_EDAS_DyAr_Free;\
{_Code}\
_p_stElement_->d_vElement = NULL;\
/*
* Reduce num of values if we delete last one.
*/\
if(_uiDPos_ == (_Array)->uiNumValues - 1)\
(_Array)->uiNumValues--;\
}
/*
* To delete all elements of a dynamic array.
* _Cast : Cast of element to delete.
* _Array : Array to delete the element.
* _Code : Code to free inside the element.
* _Borne : Borne to stop deletion.
*
* _Code MUST SET ALLOCATION MODE FOR ELEMENT !!!
*/
#define _SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code, _Borne)\
{\
unsigned int _uiIndex_;\
/*
* Delete all elements.
*/\
for(_uiIndex_ = 0; _uiIndex_ < (_Array)->##_Borne; _uiIndex_++)\
if((_Array)->d_stDynArray[_uiIndex_].d_vElement != NULL)\
SCR_M_DyAr_DeleteElement(_Cast, _uiIndex_, _Array, _Code);\
/*
* Free array.
*/\
if((_Array)->d_stDynArray)\
{\
fn_v_Mem_SetMode(0);\
SCR_M_Mem_Free((_Array)->d_stDynArray);\
}\
(_Array)->uiNumValues = (_Array)->uiMaxValues = 0;\
}
#define SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code)\
_SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code, uiNumValues);
#define SCR_M_DyAr_DeleteAllElementsStatic(_Cast, _Array, _Code)\
_SCR_M_DyAr_DeleteAllElements(_Cast, _Array, _Code, uiMaxValues);
/*
* A macro to delete an element depending on its priority.
* For a static allocation, element is not deleted but is erased from the dynamic array.
* So we assume that static block will be destroyed later.
*/
#define SCR_M_DyAr_DeleteElementWithMemLevel(_Cast, _Array, _Code, _PrioMin, _PrioMax)\
{\
_Cast *_p_stPointer_;\
unsigned int _uiPos_;\
char _cMode_;\
_uiPos_ = 0;\
SCR_M_DyAr_GetNextElement(_Cast, _uiPos_, _p_stPointer_, _Array);\
while(_p_stPointer_)\
{\
if\
(\
((_p_stPointer_)->stHeader.ucMemLevel >= (_PrioMin))\
&& ((_p_stPointer_)->stHeader.ucMemLevel <= (_PrioMax))\
)\
{\
if\
(\
((_p_stPointer_)->stHeader.ucMemLevel >= E_ucScrMaxBlocksNb)\
|| (g_a_ul_Mem_BlocAllocationSize[(_p_stPointer_)->stHeader.ucMemLevel] == 0)\
)\
{\
_cMode_ = 0;\
SCR_M_DyAr_DeleteElement(_Cast, _uiPos_, &(_Array), _Code);\
}\
else\
{\
_cMode_ = 1;\
SCR_M_DyAr_DeleteElementNoAlloc(_uiPos_, &(_Array), _Code);\
}\
}\
_uiPos_++;\
SCR_M_DyAr_GetNextElement(_Cast, _uiPos_, _p_stPointer_, _Array);\
}\
}
/*
* A macro to get an element.
* _Cast : Cast of structure to get.
* _Pos : Position of element to get.
* _Pointer : To receive address of element.
* _Array : Array concerned.
*/
#define SCR_M_DyAr_GetElement(_Cast, _Pos, _Pointer, _Array)\
{\
_Pointer = ((_Cast *) (_Array.d_stDynArray[_Pos].d_vElement));\
SCR_M_Dbg_AssertStruct_P(_Cast, _Pointer);\
}
/*
* A macro to search the first valid element of a dynamic array.
* _Cast : Cast of element to return.
* _Pos : Pos of found element and current position to search.
* _Pointer : To receive address of element (NULL if not).
* _Array : Array to search.
*/
#define SCR_M_DyAr_GetNextElement(_Cast, _Pos, _Pointer, _Array)\
{\
while((_Pos) < (_Array).uiNumValues)\
{\
if((_Array).d_stDynArray[_Pos].eState != SCR_EDAS_DyAr_Free)\
{\
SCR_M_DyAr_GetElement(_Cast, _Pos, _Pointer, _Array);\
break;\
}\
(_Pos)++;\
}\
if((_Pos) >= (_Array).uiNumValues)\
_Pointer = NULL;\
}
/*
* A macro to search an element in an array.
* _Cast : Cast of structure to get.
* _Pos : Position of element to get.
* _Pointer : To receive address of element.
* _Array : Array concerned.
* _Test : Lines to test if this is the good element.
*/
#define SCR_M_DyAr_SearchElement(_Cast, _Pos, _Pointer, _Array, _Test)\
{\
_Pos = 0;\
SCR_M_DyAr_GetNextElement(_Cast, _Pos, _Pointer, _Array);\
while((_Pointer) != NULL)\
{\
if(_Test)\
break;\
(_Pos)++;\
SCR_M_DyAr_GetNextElement(_Cast, _Pos, _Pointer, _Array);\
}\
}
/*
* Simply pack an array by just adjusting its size.
* _Cast : Cast of an element in array.
* _Array : Array to realloc.
*/
#define SCR_M_DyAr_SimplePackArray(_Cast, _Array)\
{\
/* Realloc array */\
if((_Array).uiNumValues != (_Array).uiMaxValues)\
{\
if((_Array).uiNumValues == 0)\
{\
fn_v_Mem_SetMode(0);\
SCR_M_Mem_Free((_Array).d_stDynArray);\
}\
else\
{\
fn_v_Mem_SetMode(0);\
SCR_M_Mem_Realloc(SCR_tdst_DyAr_Element, (_Array).d_stDynArray, (_Array).d_stDynArray, (_Array).uiNumValues, 0);\
}\
(_Array).uiMaxValues = (_Array).uiNumValues;\
}\
}
/*
* To reduce the size of a dynamic array by filliing the free places.
* _Cast : Cast of an element.
* _Array : Dynamic array to reduce.
* _Code : Eventual code to execute.
*/
#define SCR_M_DyAr_PackArray(_Cast, _Array, _Code)\
{\
_Cast *_p_stPointer_;\
int _DyAr_iEndPos_;\
int _DyAr_iBegPos_ = (_Array).uiNumValues - 1;\
if(_Array.uiNumValues)\
{\
/* Search the last non free place of array */\
while\
(\
(_DyAr_iBegPos_ >= 0)\
&& ((_Array).d_stDynArray[_DyAr_iBegPos_].eState == SCR_EDAS_DyAr_Free)\
)\
{\
_DyAr_iBegPos_--;\
(_Array).uiNumValues--;\
}\
_DyAr_iEndPos_ = _DyAr_iBegPos_;\
while(_DyAr_iBegPos_ >= 0)\
{\
/* Search the last free place in array */\
while\
(\
(_DyAr_iBegPos_ >= 0)\
&& ((_Array).d_stDynArray[_DyAr_iBegPos_].eState != SCR_EDAS_DyAr_Free)\
)\
{\
_DyAr_iBegPos_--;\
}\
/* We find a home and must fill it with the last non free of array */\
if(_DyAr_iBegPos_ >= 0)\
{\
memcpy\
(\
&((_Array).d_stDynArray[_DyAr_iBegPos_]),\
&((_Array).d_stDynArray[_DyAr_iEndPos_]),\
sizeof(SCR_tdst_DyAr_Element)\
);\
(_Array).uiNumValues--;\
{_Code;}\
_DyAr_iBegPos_--;\
_DyAr_iEndPos_--;\
}\
}\
}\
if(_Array.uiMaxValues)\
{\
/* Simple pack array */\
SCR_M_DyAr_SimplePackArray(_Cast, _Array);\
/* Recompute "uiIndexInArray" field */\
for(_DyAr_iBegPos_ = 0; (unsigned int) _DyAr_iBegPos_ < (_Array).uiNumValues; _DyAr_iBegPos_++)\
{\
SCR_M_DyAr_GetElement(_Cast, _DyAr_iBegPos_, _p_stPointer_, _Array);\
_p_stPointer_->stHeader.uiIndexInArray = _DyAr_iBegPos_;\
}\
}\
}
#endif /* !__SCR_DyAr_h__Macros && !__Only_Types__ */
/*
*=================================================================================================
* Protos.
*=================================================================================================
*/
#if !defined(__SCR_DyAr_h__Protos) && !defined(__Only_Types__)
#define __SCR_DyAr_h__Protos
extern void fn_v_DyAr_InitArray(SCR_tdst_DyAr_Description *);
extern unsigned int fn_ui_DyAr_AllocateElement(SCR_tdst_DyAr_Description *, char);
#endif /* !__SCR_DyAr_h__Protos && !__Only_Types__ */