#ifndef __SNARLT_H__
#define __SNARLT_H__

#ifdef  __cplusplus
extern "C" {
#endif

/* Relocation table : defs and macro for special load mode used by protection */
#define SNA_M_ProtectRelocationTableSize		20

/* Variables that contains the id of next relocation to load. */
extern unsigned char SNA_g_ucNextRelocationTableToLoad[];
extern DWORD	SNA_g_a_dwInitKeyRelocationTableLoaded[SNA_M_ProtectRelocationTableSize];
extern DWORD	SNA_g_a_dwProtectKeyRelocationTableLoaded[SNA_M_ProtectRelocationTableSize];
extern DWORD	SNA_g_dwNumberOfRelocationTableLoaded;

/* File types */
#define SNA_C_ucSNARelocationTable               0	/* alphabetical order of extension */
#define SNA_C_ucGlobalPointersRelocationTable    1
#define SNA_C_ucSoundRelocationTable             2
#define SNA_C_ucTexturesRelocationTable          3
#define SNA_C_ucLipsSyncRelocationTable          4 /* Not used in Rayman II. */


/* Macros to manipulate the global variable */
#define SNA_M_vSetNextRelocationFileToLoad( ucLevelNumber, ucFileType ) \
{ \
	SNA_g_ucNextRelocationTableToLoad[0] = (unsigned char)ucLevelNumber; \
	SNA_g_ucNextRelocationTableToLoad[1] = (unsigned char)ucFileType; \
}

#define SNA_M_vSetNextRelocationFileTypeToLoad( ucFileType ) \
	SNA_g_ucNextRelocationTableToLoad[1] = (unsigned char)ucFileType;

#define SNA_M_vSetNextRelocationFileLevelToLoad( ucFileType ) \
	SNA_g_ucNextRelocationTableToLoad[0] = (unsigned char)ucLevelNumber;

#define SNA_M_vUpdateOccurrenceToLoad() \
{ \
	SNA_g_ucNextRelocationTableToLoad[2] += (unsigned char)PTC_fn_lGetRandomRange(1,6);\
}

extern CPA_EXPORT unsigned char SNA_fn_ucGetLevelID( char *_p_szLevelName );
extern CPA_EXPORT tdstRelocTable *SNA_fn_pLoadRelocationTable();
extern CPA_EXPORT void SNA_fn_pFreeRelocationTable(tdstRelocTable * p_stRelocTable);

/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */

/* used to load unused relocTable (for protection) */
extern tdstRelocTable *SNA_g_PTCRelocationTable;

/* ---------------------------------------------------------------------------------------------- */

#define SNA_M_FreeRelocationTable() \
{ \
	if (SNA_g_PTCRelocationTable)	SNA_fn_pFreeRelocationTable(SNA_g_PTCRelocationTable); \
	SNA_g_PTCRelocationTable = NULL; \
}

#define SNA_M_LoadUsedRelocationTable() \
{ \
	SNA_M_FreeRelocationTable(); \
	SNA_g_PTCRelocationTable = SNA_fn_pLoadRelocationTable(); \
}

/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */

/*------------------------------------------------------------------------*/
#if defined(PTC_SYSTEM_ACTIVED) /* { */
/*------------------------------------------------------------------------*/

#define SNA_M_LoadUnusedRelocationTable() \
{ \
	if (SNA_fn_bBigFileUsed() /* && PTC_fn_lGetRandom() & 0x1*/) \
	{ \
		SNA_g_ucNextRelocationTableToLoad[0] = (unsigned char)(g_stEngineStructure.ucNumberOfLevels - (SNA_g_ucNextRelocationTableToLoad[0] + SNA_g_ucNextRelocationTableToLoad[1])); \
		SNA_g_ucNextRelocationTableToLoad[1] = (unsigned char)(4 - SNA_g_ucNextRelocationTableToLoad[1]); \
		SNA_M_vUpdateOccurrenceToLoad(); \
		SNA_M_LoadUsedRelocationTable(); \
	} \
}

#define SNA_M_InitLoadRelocationTable() \
{ \
	SNA_g_ucNextRelocationTableToLoad[0] = (unsigned char)PTC_fn_lGetRandomRange(0,g_stEngineStructure.ucNumberOfLevels); \
	SNA_g_ucNextRelocationTableToLoad[1] = (unsigned char)PTC_fn_lGetRandomRange(0,3); \
	SNA_g_ucNextRelocationTableToLoad[2] = (unsigned char)PTC_fn_lGetRandomRange(0,20);\
	SNA_g_dwNumberOfRelocationTableLoaded = 0; \
}

#define SNA_M_ReInitLoadRelocationTable() \
{ \
	SNA_g_dwNumberOfRelocationTableLoaded = 0; \
}

/*------------------------------------------------------------------------*/
#else /* } PTC_SYSTEM_ACTIVED { */
/*------------------------------------------------------------------------*/

#define SNA_M_LoadUnusedRelocationTable()
#define SNA_M_InitLoadRelocationTable()
#define SNA_M_ReInitLoadRelocationTable()

/*------------------------------------------------------------------------*/
#endif /* } PTC_SYSTEM_ACTIVED */
/*------------------------------------------------------------------------*/

/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
INLINE DWORD SNA_fn_dwGetCryptKey(DWORD _dwValue)
{
	DWORD dwTmp;

    _dwValue ^= 123459876;
    dwTmp = _dwValue / 127773;
    _dwValue = 16807 * (_dwValue - dwTmp * 127773) - 2836 * dwTmp;
    if (_dwValue < 0) _dwValue += 2147483647;

	return _dwValue;
}

INLINE DWORD SNA_fn_dwGetCryptKeyRelocationTable()
{
	DWORD dwValue = *((DWORD*)SNA_g_ucNextRelocationTableToLoad);

	return SNA_fn_dwGetCryptKey (dwValue);
}

INLINE DWORD SNA_fn_dwGetProtectionKey(DWORD _dwValue)
{
	DWORD dwTmp;

    _dwValue ^= 123459876;
    dwTmp = _dwValue / 44488;
    _dwValue = 48271 * (_dwValue - dwTmp * 44488) - 3399 * dwTmp;
    if (_dwValue < 0) _dwValue += 2147483647;

	return _dwValue;
}

INLINE DWORD SNA_fn_dwGetProtectionKeyRelocationTable()
{
	DWORD dwValue = *((DWORD*)SNA_g_ucNextRelocationTableToLoad);

	return SNA_fn_dwGetProtectionKey (dwValue);
}
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */

 
#ifdef  __cplusplus
}/* extern "C" */
#endif
 
#endif /* __SNAGLOB_H__*/
