/*--------------------------------------------------------------------*
 * SnaNoScr.c	written by Guillaume Souchet (based on Michael Ryssen's code)
 *
 * Purpose : save and load binarized game desc scripts
 *		 (game.dsc, game.mem, level.mem, level.dsc)
 *--------------------------------------------------------------------*/


#include "ToolsCPA.h"
#include "acp_opfi.h"
#include "GAM.h"
#ifdef USE_IPT_DX5
#include "INO_DX5.h"
#define D_IPT_Input_StructureDefine
#include "IPT_DX5.h"
#include "IPT_DX5\IPT_str.h"
#undef D_IPT_Input_StructureDefine
#endif /* USE_IPT_DX5 */
#include "sna.h"
#include "snafile.h"
#include "Structur/Input_s.h"
#define D_RND_Input_StructureDefine
#include "RND\RND_str.h"
#include "RND\MemRND.h"
#include "RND\ErrRND.h"


/* To initialise script mem. */
#if !defined(RETAIL)
extern unsigned long g_SCR_a9MemTable[9];
#endif


// If you want binary files to be more human readable, 
// but not readable by the progam anymore, uncomment this line
//#define EXPLICIT_BINARY_FILES

extern char g_cCDROM;
extern char g_sLanguage[255];
extern int g_iSoundOnHD;
extern int g_iComplete;

struct SNA_tdstFile_ g_stDscFile;
//FILE *&g_stDscFile = NULL;
unsigned char g_ucMemDescSnapshot = SNA_C_LoadScriptDsc;
enum tdeDscFileType_ SNA_g_eFileCurrentlyOpened = SNA_C_NoDscFile;



// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Return Load/Save state for binary descriptions
 *
 * SNA_C_LoadScriptDsc (=0)
 * SNA_C_LoadBinaryDsc (=1)
 * SNA_C_SaveBinaryDsc (=2)
 */
unsigned char SNA_fn_ucGetLoadDscType()
{
	return g_ucMemDescSnapshot;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Sets Load/Save state for binary descriptions
 * (usually this is done at initialisation time (command line, etc)) 
 *
 * SNA_C_LoadScriptDsc (=0)
 * SNA_C_LoadBinaryDsc (=1)
 * SNA_C_SaveBinaryDsc (=2)
 */
void SNA_fn_vSetLoadDscType( unsigned char _ucType )
{
	g_ucMemDescSnapshot = _ucType;

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Closes the currently used ".dsb" file.
 */
void SNA_fn_vCloseDscFile()
{
	if( g_stDscFile.hFile != INVALID_HANDLE_VALUE)
		SNA_fn_bFClose( &g_stDscFile );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Opens a .dsb file.
 *
 * Params : 
 *	 - _eFile : Game file or Level file.
 *	 - _szMode : mode for opening the file (ie "rb", "a+b") 
 *
 * This function is usually called by macros (SNA_M_BeginAppendToDscFile and SNA_M_BeginReadFromDscFile)
 */
void SNA_fn_vOpenDscFile( enum tdeDscFileType_ _eFile, char *_szMode )
{
	char a256_cFileName[256];
	ACP_tdxBool bOpenFileOK;
	unsigned char ucMode;

	if( g_stDscFile.hFile != INVALID_HANDLE_VALUE)
		SNA_fn_vCloseDscFile();

	switch( _eFile )
	{
	case SNA_C_NoDscFile :
	break;

	case SNA_C_GameDscFile :
		//sprintf( a256_cFileName, "%s\\%s", fn_szGetGameDataPath(), SNA_C_GameDscFileName );
		strcpy(a256_cFileName , fn_szGetGameDataPath());
		strcat(a256_cFileName , "\\");
		strcat(a256_cFileName , SNA_C_GameDscFileName);

		break;

	case SNA_C_LevelDscFile :
		//sprintf( a256_cFileName,"%s\\%s\\%s.dsb",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
		strcpy(a256_cFileName , fn_szGetLevelsDataPath());
		strcat(a256_cFileName , "\\");
		strcat(a256_cFileName , fn_p_szGetLevelName());
		strcat(a256_cFileName , "\\");
		strcat(a256_cFileName , fn_p_szGetLevelName());
		strcat(a256_cFileName , ".");
		strcat(a256_cFileName , "d");
		strcat(a256_cFileName , "s");
		strcat(a256_cFileName , "b");
		break;

	default:
		return;
	}

	ucMode = (_szMode[0] == 'w' ? SNA_C_ucWrite : SNA_C_ucRead);

#ifdef EXPLICIT_BINARY_FILES
	// If we want (almost)text files, do not crypt them
	SNA_fn_bFOpen( a256_cFileName, ucMode, 0, &g_stDscFile );
#else
	// Else, use encryption.
	ACP_M_OPENFILE(SNA_fn_bFOpen,bOpenFileOK,FALSE,a256_cFileName,(a256_cFileName,ucMode,SNA_C_ucUseEncryption,&g_stDscFile));
	//SNA_fn_bFOpen( a256_cFileName, _szMode, SNA_C_ucUseEncryption, &g_stDscFile );

	assert( bOpenFileOK );			// If error: File for level description is not found !

	// uncommment this to set the crypt key to a custom value
//	SNA_fn_vSetCryptKey( 0x586ad36e, &g_stDscFile );

#endif
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#ifndef RETAIL
/**
 * Opens a .dsb file for writing datas.
 * 
 * Param : 
 *   - _eFile : Game file or Level file
 *
 * Usually called by SNA_M_BeginWriteToDscFile
 */
void SNA_fn_vOpenDscFileForWriting( enum tdeDscFileType_ _eFile )
{
/*
	static unsigned char ucFirstOpening[2] = { 1, 1 };

	if ( ucFirstOpening[_eFile-1] )
	{
		 ucFirstOpening[_eFile-1] = 0;
		 SNA_fn_vOpenDscFile( _eFile, "wb" );
	}
	else
	{
		SNA_fn_vOpenDscFile( _eFile, "a+b" );
	}
*/
	DWORD dwWritten;

	SNA_fn_vOpenDscFile( _eFile, "wb" );
	// Write Crypt Key (by using fwrite to avoid use of checksum and encryption)
	SNA_M_WRITEFILE(g_stDscFile.hFile , &g_stDscFile.ulCryptKey , sizeof(g_stDscFile.ulCryptKey) , &dwWritten , NULL);
}
#endif

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void SNA_fn_vOpenDscFileForReading( enum tdeDscFileType_ _eFile )
{
	DWORD dwRead;

	SNA_fn_vOpenDscFile( _eFile, "rb" );
	// Read Crypt Key (by using fread to avoid use of checksum and encryption)
	g_stDscFile.bReadSuccess = SNA_M_READFILE(g_stDscFile.hFile , &g_stDscFile.ulCryptKey , sizeof(g_stDscFile.ulCryptKey) , &dwRead , NULL);

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Returns TRUE if a file is currently opened.
 */
ACP_tdxBool SNA_fn_bIsDscFileOpened()
{
	//return (g_stDscFile.p_xFile != NULL);
	return (g_stDscFile.hFile != INVALID_HANDLE_VALUE);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
 * Simple functions to read from and write to a dsc file
 */

/**
 * Reads a long integer from the current .dsb file.
 */
void SNA_fn_vReadLongFromFile( unsigned long *_p_ulLong )
{
	SNA_fn_ulFRead( _p_ulLong, 4, 1, &g_stDscFile );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Reads a long integer from the current .dsb file and returns it.
 */
long SNA_fn_lReadLongFromFile()
{
	long ulLong;
	SNA_fn_ulFRead( &ulLong, 4, 1, &g_stDscFile);
	return ulLong;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Reads a double from the current .dsb file and returns it.
 */
double SNA_fn_dfReadDoubleFromFile()
{
	double dfNumber;
	SNA_fn_ulFRead( &dfNumber, 4, 1, &g_stDscFile);
	return dfNumber;
}


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Reads a string from the current .dsb file.
 */
void SNA_fn_vReadStringFromFile( char *_szString )
{
	unsigned short uwNbChar;

	SNA_fn_ulFRead( &uwNbChar, 2, 1, &g_stDscFile );
	SNA_fn_ulFRead( _szString,1, uwNbChar, &g_stDscFile );
#ifdef _DEBUG
	if ( uwNbChar>255 )
		OutputDebugString( "String too long ! (>255 char) \n" );
	OutputDebugString( _szString );
	OutputDebugString( "\n" );
#endif
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
 * Reads a block of datas from the current .dsb file.
 */
void SNA_fn_vReadBlockFromFile( char *_p_cBlock, unsigned long _ulSize )
{
	SNA_fn_ulFRead( _p_cBlock, 1, _ulSize, &g_stDscFile );
}


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#ifndef RETAIL
/**
 * Functions for writing in a .dsb file.
 * All these functions supports the EXPLICIT_BINARY_FILES define 
 * that makes .dsb files more readable.
 * How does it work ? hehe...
 * It is very simple. Instead of writing value in binary format, it writes 
 * them in string format.
 * For example, if (long)1234 is to be written in a dsb file 
 * and if EXPLICIT_BINARY_FILES is defined, (char *)"1234" will be written
 * instead of the binary représentation of 1234.
 *
 * With that, you are able to read any.dsb with a text editor and check its content.
 * (you can compare keywords with those defined in snanoscr.h for example...)
 */

/*
 * Writes a long to the current .dsb file 
 */
void SNA_fn_vWriteLongToCurrentDscFile( unsigned long _ulLong )
{
#ifdef EXPLICIT_BINARY_FILES
	char acbuffer[10];
	
	sprintf( acbuffer, "%li ", _ulLong );
	SNA_fn_ulFWrite( acbuffer, strlen(acbuffer), 1, &g_stDscFile );
#else /* ! EXPLICIT_BINARY_FILES */
	SNA_fn_ulFWrite(&_ulLong,4,1,&g_stDscFile);
#endif /* EXPLICIT_BINARY_FILES */
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
 * Writes a double to the current .dsb file 
 */
void SNA_fn_vWriteDoubleToCurrentDscFile( double _dfNumber )
{
#ifdef EXPLICIT_BINARY_FILES
	char acbuffer[20];

	sprintf( acbuffer, "%f ", _dfNumber );
	SNA_fn_ulFWrite( acbuffer, strlen(acbuffer), 1, &g_stDscFile );
#else /* ! EXPLICIT_BINARY_FILES */
	SNA_fn_ulFWrite(&_dfNumber,sizeof(double),1,&g_stDscFile);
#endif /* EXPLICIT_BINARY_FILES */
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
 * Writes a string to the current dsb file 
 */
void SNA_fn_vWriteStringToCurrentDscFile( char *_szString )
{
	unsigned short uwNbChar;

	uwNbChar=strlen( _szString )+1;
#ifdef EXPLICIT_BINARY_FILES
	SNA_fn_ulFWrite( " ", 1, 1, &g_stDscFile );
#else
	SNA_fn_ulFWrite( &uwNbChar, 2, 1, &g_stDscFile );
#endif

	SNA_fn_ulFWrite( _szString, 1, uwNbChar, &g_stDscFile );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
 * Writes a block of datas to the current .dsb file 
 */
void SNA_fn_vWriteBlockToCurrentDscFile( char *_d_cData, unsigned long _ulSize )
{
#ifdef EXPLICIT_BINARY_FILES
	char szBuffer[50];
	sprintf( szBuffer, " \r\n Block of data (%li bytes) ", _ulSize );
	SNA_fn_ulFWrite( szBuffer, 1, strlen( szBuffer ), &g_stDscFile );
#else /* ! EXPLICIT_BINARY_FILES */
	SNA_fn_ulFWrite( _d_cData, 1, _ulSize, &g_stDscFile );
#endif /* ! EXPLICIT_BINARY_FILES */
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Writes an entry (id of entry (=>snanoscr.h) + parameter of entry) to the current .dsb file.
 */
void SNA_fn_vWriteNoParamEntryToCurrentDscFile( unsigned long _ulEntryType )
{
#ifdef EXPLICIT_BINARY_FILES
	SNA_fn_ulFWrite( "\r\n", 2, 1, &g_stDscFile );
#endif

	SNA_fn_vWriteLongToCurrentDscFile( _ulEntryType );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void SNA_fn_vWriteLongEntryToCurrentDscFile( unsigned long ulEntryType, unsigned long ulEntryParam )
{
#ifdef EXPLICIT_BINARY_FILES
	SNA_fn_ulFWrite( "\r\n", 2, 1, &g_stDscFile );
#endif

	SNA_fn_vWriteLongToCurrentDscFile( ulEntryType );
	SNA_fn_vWriteLongToCurrentDscFile( ulEntryParam );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void SNA_fn_vWrite2LongEntryToCurrentDscFile( 
    unsigned long ulEntryType,
    unsigned long ulEntryParam,
    unsigned long ulEntryParam2 )
{
	SNA_fn_vWriteLongEntryToCurrentDscFile( ulEntryType, ulEntryParam );
	SNA_fn_vWriteLongToCurrentDscFile( ulEntryParam2 );
}


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void SNA_fn_vWriteStringEntryToCurrentDscFile( unsigned long ulEntryType, char *szEntryParam )
{
#ifdef EXPLICIT_BINARY_FILES
	SNA_fn_ulFWrite( "\r\n", 2, 1, &g_stDscFile );
#endif

	SNA_fn_vWriteLongToCurrentDscFile( ulEntryType );
	SNA_fn_vWriteStringToCurrentDscFile( szEntryParam );
}

void SNA_fn_vWrite3StringsEntryToCurrentDscFile( unsigned long ulEntryType, char *szEntryParam0, char *szEntryParam1,char *szEntryParam2 )
{
#ifdef EXPLICIT_BINARY_FILES
	SNA_fn_ulFWrite( "\r\n", 2, 1, &g_stDscFile );
#endif

	SNA_fn_vWriteLongToCurrentDscFile( ulEntryType );
	SNA_fn_vWriteStringToCurrentDscFile( szEntryParam0 );
	SNA_fn_vWriteStringToCurrentDscFile( szEntryParam1 );
	SNA_fn_vWriteStringToCurrentDscFile( szEntryParam2 );
}

void SNA_fn_vWriteIntArrayEntryToCurrentDscFile( unsigned long ulEntryType, int iEntryParam0, int *p_iArray )
{
	SNA_fn_vWriteLongToCurrentDscFile( ulEntryType );
	SNA_fn_vWriteLongToCurrentDscFile( iEntryParam0 ); // Nb elements
	SNA_fn_vWriteBlockToCurrentDscFile((char *)p_iArray, sizeof(int)*iEntryParam0);
}

#endif /* RETAIL */

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
 * Return ID of next section if we are positionned
 * at the beginning of a section or returns EndOfSection if we are 
 * at the end of the file.
 * Otherwise (bad position), result is useless.
 */ 
unsigned long SNA_fn_ulTellWitchSectionInDscFile()
{
	long lSectionMark;

	if ( g_stDscFile.hFile == INVALID_HANDLE_VALUE) 
		return -1;

	if (!g_stDscFile.bReadSuccess)
		return SNA_C_ulEndOfDescSection;


	if( SNA_fn_ulFRead( &lSectionMark, sizeof(long), 1, &g_stDscFile ) < 1 )
	{
		lSectionMark = SNA_C_ulEndOfDescSection;
	}
	return lSectionMark;
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Functions related to game.dsc
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * WARNING : all functions that read a part from a .dsb file do NOT check 
 *			 if they are at the beginning of the section they should read.
 *			 If such a function is called when the current file position
 *			 is wrong, the program may crash...
 */



// Read level names
void SNA_fn_vReadLevelNameFromFile()
{
	unsigned long ulKeyWord;
	char szParam[50];
	unsigned long ulParam;

	// Read title parameters
	SNA_fn_vReadLongFromFile( &ulParam );
#ifndef RETAIL
	 g_cChooseLevel = -1;
#endif /* !RETAIL */
	g_stEngineStructure.ucNumberOfLevels = 0;
	g_stEngineStructure.ucCurrentLevel = (unsigned char)ulParam;

	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch ( ulKeyWord )
		{
			case SNA_C_ul_LevelName :
				SNA_fn_vReadStringFromFile( szParam );
				if ( !g_cIsLevelOk )
				{
					if ( 
						(g_stEngineStructure.ucNumberOfLevels == g_stEngineStructure.ucCurrentLevel) 
						|| (g_stEngineStructure.ucNumberOfLevels == 0)
						 )
						fn_vSetFirstLevelName( szParam );
				}
				strcpy( g_stEngineStructure.a_szLevelName[ g_stEngineStructure.ucNumberOfLevels++], szParam );
				break;

#if defined(_DEBUG)
		default:
			assert(0);        // Unknown Data in DSB File !!!!!
			break;
#endif

		}
	}
}


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Read random manager initialisation
void SNA_fn_vReadRandomDescFromFile()
{
	unsigned long ulKeyWord;
	unsigned long ulParam;

	SNA_fn_vReadLongFromFile( &ulParam );
	RND_g_stRandomStructure.ulSizeOfTable = ulParam;
	Mmg_M_InitBlock
	( 
		RND, E_ucRNDMemoryBlock, 
		C_uwAllocSize+RND_g_stRandomStructure.ulSizeOfTable*sizeof(unsigned long)
	);
	Mmg_M_SetModeAlloc4Ch( RND, E_ucRNDMemoryBlock, C_ucMmgDefaultChannel );
	RND_g_stRandomStructure.p_ulTable = 
		Mmg_fn_p_vAlloc4Ch
		( 
			RND_g_stRandomStructure.ulSizeOfTable*sizeof(unsigned long), 
			C_ucMmgDefaultChannel
		);

	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch ( ulKeyWord )
		{
			case SNA_C_ul_RandomComputeTable :
				RND_fn_vComputeRandomTable();
				RND_fn_vRemapRandomTable();
				break;

			case SNA_C_ul_RandomReadTable :
				SNA_fn_vReadBlockFromFile
				(
					(char *)RND_g_stRandomStructure.p_ulTable,
					sizeof(unsigned long)*RND_g_stRandomStructure.ulSizeOfTable
				);
				RND_fn_vRemapRandomTable();
				break;

#if defined(_DEBUG)
		default:
			assert(0);        // Unknown Data in DSB File !!!!!
			break;
#endif

		}
	}
}

// - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -

// Read directories description
void SNA_fn_vReadDirectoriesDescFromFile()
{
	unsigned long ulKeyWord;
	char szParam[50];
	char a256_cDataDirectory[256];
	char szPath[256];
	char szFileName[256];
	static char szInventorDirectory[_MAX_PATH];

	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch( ulKeyWord )
		{
		case SNA_C_ul_DirectoryOfEngineDLL:
			SNA_fn_vReadStringFromFile( szParam );
			fn_vSetEngineDLLPath(szParam);
			break;

		case SNA_C_ul_DirectoryOfGameData :
			SNA_fn_vReadStringFromFile( szParam );
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(szParam);
#endif
			break;

		case SNA_C_ul_DirectoryOfTexts :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetTextsDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);

			sprintf( szPath,"%s\\%s", a256_cDataDirectory, g_sLanguage );
			SCR_fn_v_RdL0_RegisterPath( szPath );
#endif
			break;

		case SNA_C_ul_DirectoryOfWorld :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetWorldDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfLevels :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetLevelsDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfFamilies :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetFamiliesDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfCharacters :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetCharactersDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfAnimations :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetAnimDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfGraphicsClasses :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetGraphicsClassesDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfGraphicsBanks :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetGraphicsBanksDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfMechanics :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetMechanicsDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfSound :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetGraphicsClassesDataPath(a256_cDataDirectory);
//#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
//#endif
			strcpy(szFileName, g_a64_cGameDataDirectory);
			strcat(szFileName,szParam);
			fn_vSetSoundDataPath(szFileName);
//#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(szFileName);
//#endif
			strcat(szFileName,"\\");
			SND_fn_vAddDataDirectory(szFileName);
			//sprintf(szPath,"%s%s\\",szFileName,g_sLanguage);
			strcpy(szPath,szFileName);
			strcat(szPath,g_sLanguage);
			strcat(szPath,"\\");
			SND_fn_vAddDataDirectory(szPath);
			break;

		case SNA_C_ul_DirectoryOfVisuals :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetVisualMaterialDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfEnvironment :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetEnvironmentDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfMaterials :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetCollideMaterialDataPath(a256_cDataDirectory);
			fn_vSetSoundMaterialDataPath(a256_cDataDirectory);
			fn_vSetMechanicsMaterialDataPath(a256_cDataDirectory);
			fn_vSetGameMaterialDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfSaveGame :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetSaveGameDataPath(a256_cDataDirectory);
			break;

		case SNA_C_ul_DirectoryOfExtras :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetExtrasDataPath(a256_cDataDirectory);
			break;

		case SNA_C_ul_DirectoryOfTexture :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetTexturesDataPath(a256_cDataDirectory);
			GLI_vSetPathOfTexture(fn_szGetTexturesDataPath());
			break;

		case SNA_C_ul_DirectoryOfVignettes :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetVignettesDataPath(a256_cDataDirectory);
			break;

		case SNA_C_ul_DirectoryOfOptions :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetOptionsDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

		case SNA_C_ul_DirectoryOfLipsSync :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
			//sprintf(szPath,"%s\\%s",a256_cDataDirectory,g_sLanguage);
			strcpy(szPath,a256_cDataDirectory);
			strcat(szPath,"\\");
			strcat(szPath,g_sLanguage);
			fn_vSetSyncLipsDataPath(szPath);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(szPath);
#endif
			break;

		case SNA_C_ul_DirectoryOfZdx :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetZdxDataPath(a256_cDataDirectory);
			break;

		case SNA_C_ul_DirectoryOfEffects :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(a256_cDataDirectory, g_a64_cGameDataDirectory);
			strcat(a256_cDataDirectory,szParam);
			fn_vSetEffectsDataPath(a256_cDataDirectory);
#ifndef RETAIL
			SCR_fn_v_RdL0_RegisterPath(a256_cDataDirectory);
#endif
			break;

#if defined(_DEBUG)
		default:
			assert(0);        // Unknown Data in DSB File !!!!!
			break;
#endif

		}

	}


#if ( !defined( U64 ) && !defined( RETAIL ) )
	if (!g_iComplete)
	{
		strcpy( szFileName, fn_szGetGameDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetWorldDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);

		strcpy( szFileName, fn_szGetTextsDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		sprintf(szFileName,"%s\\%s",szPath,g_sLanguage);
		SCR_fn_v_RdL0_RegisterPath(szFileName);

		strcpy( szFileName, fn_szGetFamiliesDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetCharactersDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetLevelsDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetAnimDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetGameMaterialDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetVisualMaterialDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetSoundDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcat(szPath,"\\");
		SND_fn_vAddDataDirectory(szPath);
		sprintf(szFileName,"%s%s",szPath,g_sLanguage);
		SCR_fn_v_RdL0_RegisterPath(szFileName);
		strcat(szFileName,"\\");
		SND_fn_vAddDataDirectory(szFileName);

		strcpy( szFileName, fn_szGetGraphicsClassesDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetGraphicsBanksDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetMechanicsDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetEnvironmentDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetOptionsDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetSyncLipsDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		strcpy( szFileName, fn_szGetEffectsDataPath() );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);

		strcpy( szFileName, szInventorDirectory );
		sprintf(szPath,"%c:\\%s",g_cCDROM,szFileName);
		SCR_fn_v_RdL0_RegisterPath(szPath);
		sprintf(szFileName,"%s\\%s",szPath,g_sLanguage);
		SCR_fn_v_RdL0_RegisterPath(szFileName);
	}
#endif /* ( !defined( U64 ) && !defined( RETAIL ) ) */

}




/* - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 * Functions related to game.mem and level.mem
 * - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 */

/*
 * Read a memory description file or portion of file and do the memory init.
 */
void SNA_fn_vReadMemoryDescFromFile()
{
	static unsigned char ucInitLevelBlock = 2;    // To initialise level mem block the first time only (and not at each level change).
	unsigned long ulKeyWord, ulParam;
#ifndef RETAIL 
	unsigned long ulParam2;        // For script memory only
#endif

	/*
	 * Read each keyword (=memory type) in the file
	 * and do the init accordingly
	 */
	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch ( ulKeyWord )
		{
			/* Game Memory (game.mem) */
			case SNA_C_ul_GAMFixMemory :
				Mmg_M_InitBlock( Game, E_ucGameFixMemory, SNA_fn_lReadLongFromFile() );
				GAM_fn_vSetGameMemoryInFix();
				break;

			case SNA_C_ul_ACPFixMemory :
				GEO_xCreateMemoryChannel( ACP_FixMemoryChannel, SNA_fn_lReadLongFromFile() );
				GEO_xSelectMemoryChannel( ACP_FixMemoryChannel );
				break;

			case SNA_C_ul_ACPTextMemory :
				GEO_xCreateMemoryChannel(0, SNA_fn_lReadLongFromFile() );
				break;

			case SNA_C_ul_AIFixMemory :
				fn_vInitAIFixMemory( SNA_fn_lReadLongFromFile() );
				AI_fn_vAIUseFixMemory();
				break;

			case SNA_C_ul_TMPFixMemory :
				TMP_fn_vCreateFixMemory( SNA_fn_lReadLongFromFile() );
				break;

			case SNA_C_ul_TMPLevelMemory :
				TMP_fn_vCreateLevelMemory( SNA_fn_lReadLongFromFile() );
				break;

			case SNA_C_ul_SAIFixMemory :
				SAI_fn_vInitFixMemory( SNA_fn_lReadLongFromFile() );
				SAI_fn_vSAIUseFixMemory();
				break;

			case SNA_C_ul_IPTMemory :
				IPT_fn_vInitMemory( SNA_fn_lReadLongFromFile() );
				break;

			case SNA_C_ul_FontMemory :
				FON_fn_vFirstInitFONMemory( SNA_fn_lReadLongFromFile() );
				break;

#ifndef RETAIL
			case SNA_C_ul_ScriptMemory :
				ulParam = SNA_fn_lReadLongFromFile();
				ulParam2 = SNA_fn_lReadLongFromFile();
/*				g_SCR_a9MemTable[ ulParam ] = ulParam2; */
				g_SCR_a9MemTable[ ulParam ] = 1024 * 1024; // 1 Mo
				if( ucInitLevelBlock ) SCR_fn_v_Mem_InitWithMemLevel(g_SCR_a9MemTable);
				break;
#endif

			case SNA_C_ul_PositionMemory :
				POS_fn_vInitPosMemory( SNA_fn_lReadLongFromFile() );
				break;

			/* Level Memory (level.mem) */
			case SNA_C_ul_GAMLevelMemory :
				ulParam = SNA_fn_lReadLongFromFile();
				if( ucInitLevelBlock ) Mmg_M_InitBlock( Game, E_ucGameLevelMemory, ulParam );
				GAM_fn_vSetGameMemoryInLevel();
				break;

			case SNA_C_ul_AILevelMemory :
				ulParam = SNA_fn_lReadLongFromFile();
				if( ucInitLevelBlock ) fn_vInitAILevelMemory( ulParam );
				AI_fn_vAIUseLevelMemory();
				break;

			case SNA_C_ul_ACPLevelMemory :
				ulParam = SNA_fn_lReadLongFromFile();
				if( ucInitLevelBlock ) GEO_xCreateMemoryChannel( ACP_LevelMemoryChannel, ulParam );
				GEO_xSelectMemoryChannel( ACP_LevelMemoryChannel );
				break;

			case SNA_C_ul_SAILevelMemory :
				ulParam = SNA_fn_lReadLongFromFile();
				if( ucInitLevelBlock ) SAI_fn_vInitLevelMemory( ulParam );
				SAI_fn_vSAIUseLevelMemory();
				break;

#if defined(_DEBUG)
			default:
				assert(0);        // Unknown Data in DSB File !!!!!
				break;
#endif
		} /* End switch( ulKeyword ) */

	} /* End for ( ... ulKeyWord != SNA_C_ulEndMemory ...) */

	if( ucInitLevelBlock ) ucInitLevelBlock--;
}


/* - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 * Functions related to game.pgb and level.pgb
 * - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 */

void SNA_fn_vReadVignetteDescFromFile()
{
	unsigned long ulKeyWord;
	char szParam[150];

	/*
	 * Read each keyword in the file
	 * and do the init accordingly
	 */
	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch( ulKeyWord ) 
		{
		case SNA_C_ul_LoadLevelVignette :
			SNA_fn_vReadStringFromFile( szParam );
			strcpy(VIG_g_stActualVignette.szLevelVignetteFileName, szParam);
			VIG_fn_vLoadVignetteInStructure(&VIG_g_stActualVignette,szParam,GLI_EVF_BGR565_UL);
			break;

		case SNA_C_ul_LoadVignette :
			SNA_fn_vReadStringFromFile( szParam );
			VIG_fn_vFreeVignette(&VIG_g_stActualVignette);
			VIG_fn_vLoadVignetteInStructure(&VIG_g_stActualVignette,szParam,GLI_EVF_BGR565_UL);
			break;


		case SNA_C_ul_InitVignette :
			VIG_fn_vInitVignette();
			break;

		case SNA_C_ul_FreeVignette :
			//	 VIG_fn_vFreeMemoryVignette(&VIG_g_stActualVignette);
			break;

		case SNA_C_ul_DisplayVignette :
			//*** To front buffer ***
			VIG_fn_vDisplayVignette(&VIG_g_stActualVignette);
			//*** To back buffer ***
			VIG_fn_vDisplayVignette(&VIG_g_stActualVignette);
			break;

		case SNA_C_ul_InitBarOutlineColor :
			SNA_fn_vReadBlockFromFile
				( (char *)&VIG_g_stActualVignette.stOutsideColor, sizeof(GEO_tdstColor) );
			break;

		case SNA_C_ul_InitBarInsideColor :
			SNA_fn_vReadBlockFromFile
				( (char *)&VIG_g_stActualVignette.stInsideColor, sizeof(GEO_tdstColor) );
			break;

		case SNA_C_ul_InitBarColor :
			SNA_fn_vReadBlockFromFile
				( (char *)&VIG_g_stActualVignette.stUpLeftColor, sizeof( GEO_tdstColor ) );
			SNA_fn_vReadBlockFromFile
				( (char *)&VIG_g_stActualVignette.stUpRightColor, sizeof( GEO_tdstColor ) );
			SNA_fn_vReadBlockFromFile
				( (char *)&VIG_g_stActualVignette.stDownLeftColor, sizeof( GEO_tdstColor ) );
			SNA_fn_vReadBlockFromFile
				( (char *)&VIG_g_stActualVignette.stDownRightColor, sizeof( GEO_tdstColor ) );
			break;

		case SNA_C_ul_CreateBar :
			VIG_g_stActualVignette.ulOldBarValue = 0;
			VIG_g_stActualVignette.ulNewBarValue = 0;
			VIG_g_stActualVignette.ulBarXMinPos = (VIG_g_stActualVignette.ulWidth*SNA_fn_lReadLongFromFile())/640;
			VIG_g_stActualVignette.ulBarYMinPos = (VIG_g_stActualVignette.ulHeight*SNA_fn_lReadLongFromFile())/480;
			VIG_g_stActualVignette.ulBarXMaxPos = (VIG_g_stActualVignette.ulWidth*SNA_fn_lReadLongFromFile())/640;
			VIG_g_stActualVignette.ulBarYMaxPos = (VIG_g_stActualVignette.ulHeight*SNA_fn_lReadLongFromFile())/480;
			break;


		case SNA_C_ul_AddBar :
			VIG_fn_vAddBarToVignette(&VIG_g_stActualVignette);
			VIG_g_stActualVignette.bDisplayBar = TRUE;
			break;

		case SNA_C_ul_MaxValueBar :
//			VIG_g_stActualVignette.ulMaxBarValue = SNA_fn_lReadLongFromFile();
			SNA_fn_lReadLongFromFile();
			VIG_g_stActualVignette.ulMaxBarValue = SNA_fn_ulGetMaxVignetteValueForLevel();
			VIG_g_stActualVignette.ulActualBarValue = 0;
			break;

#if defined(_DEBUG)
			default:
				assert(0);        // Unknown Data in DSB File !!!!!
				break;
#endif
		}
	}
}


void SNA_fn_vReadBigFileDescFromFile()
{
	unsigned long	ulKeyWord;
	char		szParam[150];
	char		a256_cGameMemoryFile[256];

	/*
	 * Read each keyword in the file
	 * and do the init accordingly
	 */
	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch( ulKeyWord ) 
		{
		case SNA_C_ul_BigFileVignettes :
			SNA_fn_vReadStringFromFile( szParam );
			VIG_fn_vCloseBigFileVignette();
			strcpy(a256_cGameMemoryFile,g_a64_cGameDataDirectory);
			strcat(a256_cGameMemoryFile, szParam);
			VIG_fn_vOpenBigFileVignette(a256_cGameMemoryFile);
			break;

		case SNA_C_ul_BigFileTextures :
			SNA_fn_vReadStringFromFile( szParam );
			GLI_fn_vCloseBigFileTextures();
			strcpy(a256_cGameMemoryFile,g_a64_cGameDataDirectory);
			strcat(a256_cGameMemoryFile, szParam);
			GLI_fn_vOpenBigFileTextures(a256_cGameMemoryFile);
			break;

#if defined(_DEBUG)
			default:
				assert(0);        // Unknown Data in DSB File !!!!!
				break;
#endif
		}
	}
}


void SNA_fn_vReadDescGameOption()
{
	unsigned long ulKeyWord;
	char szParam[150];
	char szParam1[20];
	char szParam2[20];

	/*
	 * Read each keyword in the file
	 * and do the init accordingly
	 */
	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{
		switch( ulKeyWord ) 
		{
		case SNA_C_ul_DefaultFile:
			SNA_fn_vReadStringFromFile( szParam );
			fn_vSetDefaultGameOptionsFileName(szParam);
			break;
		case SNA_C_ul_CurrentFile:
			SNA_fn_vReadStringFromFile( szParam );
			fn_vSetCurrentGameOptionsFileName(szParam);
			break;	
		case SNA_C_ul_FrameSynchro:
			SNA_fn_vReadStringFromFile( szParam );
			SNA_fn_vReadStringFromFile( szParam1 );
			SNA_fn_vReadStringFromFile( szParam2 );
			GLD_vSetFrameSynchro(szParam,szParam1,szParam2);
			break;

#if defined(_DEBUG)
		default:
//			assert(0);        // Unknown Data in DSB File !!!!!
			break;
#endif

		}
	}
}

#ifdef USE_IPT_DX5

/* - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 * Functions related to Device.ipt
 * - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 */
void SNA_fn_vReadActivateDevice()
{
	unsigned long ulKeyWord;

	for
	(
		SNA_fn_vReadLongFromFile( &ulKeyWord );
		ulKeyWord != SNA_C_ulEndOfDescSection;
		SNA_fn_vReadLongFromFile( &ulKeyWord )
	)
	switch ( ulKeyWord )
	{
	case SNA_C_ul_ActivatePadAction :
		{
            unsigned long ulPadNumber = SNA_fn_lReadLongFromFile();
            if (IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_Pad00DeviceEvent+ulPadNumber] == IPT_C_ValideDevice)
            {
                INO_fn_wActivateDevice(IPT_g_hInputStructure.hDeviceHandle[IPT_E_Pad00DeviceEvent+ulPadNumber]);
                IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_Pad00DeviceEvent+ulPadNumber] = IPT_C_ActivatePadDevice;
                IPT_g_hInputStructure.ucOnePadActivate = IPT_C_ActivateDevice;
            }
		}
		break ;

	case SNA_C_ul_ActivateJoystickAction :
		{
            unsigned long ulPadNumber = SNA_fn_lReadLongFromFile();
            if (IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_Pad00DeviceEvent+ulPadNumber] == IPT_C_ValideDevice)
            {
                INO_fn_wActivateDevice(IPT_g_hInputStructure.hDeviceHandle[IPT_E_Pad00DeviceEvent+ulPadNumber]);
                IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_Pad00DeviceEvent+ulPadNumber] = IPT_C_ActivateJoystickDevice;
                IPT_g_hInputStructure.ucOnePadActivate = IPT_C_ActivateDevice;
            }
		}
		break ;

	case SNA_C_ul_ActivateKeyboardAction :
        if (IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_KeyboardDeviceEvent] == IPT_C_ValideDevice)
            IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_KeyboardDeviceEvent] = IPT_C_ActivateDevice;
		break ;

	case SNA_C_ul_ActivateMouseAction :
		INO_g_bUsingMouse = TRUE;
		IPT_fn_vCreateMouseDevice( 0 );
		if (IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_MouseDeviceEvent] == IPT_C_ValideDevice)
		{
			IPT_g_hInputStructure.p_ucValideAndActiveDevice[IPT_E_MouseDeviceEvent] = IPT_C_ActivateMouseDevice;
		}
		break ;
	}
}

#endif /* USE_IPT_DX5 */

/* - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 * Functions related to level.dsc
 * - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 */
void SNA_fn_vReadLevelDescLevelSoundBanks()
{
	unsigned long ulKeyWord;
//	char szParam[150];

	SND_fn_bStartLoadBanks();

	/*
	 * Read each keyword in the file
	 * and do the init accordingly
	 */
	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch( ulKeyWord ) 
		{
		case SNA_C_ul_LevelLoadMap :
/*			SNA_fn_vReadStringFromFile( szParam );
			SCR_fnp_st_RdL0_AnalyseSection(szParam,SCR_CDF_uw_Anl_ForceAnalyse);*/
			{
				int lNbElement;
				int a500_iArray[500];
				long i;
				
				lNbElement = SNA_fn_lReadLongFromFile();
				SNA_fn_vReadBlockFromFile((char *)a500_iArray, sizeof(int)*lNbElement);
				
				for (i=0; i < lNbElement; i++)
					SND_fn_bInitBank(a500_iArray[i]);

			}
			break;

		case SNA_C_ul_LevelLoadSoundBank :
			SND_fn_bInitBank((int)SNA_fn_lReadLongFromFile());
			break;

#if defined(_DEBUG)
		default:
			assert(0);        // Unknown Data in DSB File !!!!!
			break;
#endif
		}

	}
	SND_fn_bEndLoadBanks();
}


void SNA_fn_vReadLevelDescFromFile()
{
	unsigned long ulKeyWord;

	/*
	 * Read each keyword in the file
	 * and do the init accordingly
	 */
	for (
			SNA_fn_vReadLongFromFile( &ulKeyWord );
			ulKeyWord != SNA_C_ulEndOfDescSection;
			SNA_fn_vReadLongFromFile( &ulKeyWord )
		)
	{

		switch( ulKeyWord ) 
		{
		case SNA_C_ul_NumberOfAlways :
			g_stAlways.ulMaxNumberOfAlways = SNA_fn_lReadLongFromFile();
			break;

		case SNA_C_ul_LevelDscLevelSoundBanks :
			SNA_fn_vReadLevelDescLevelSoundBanks();
			break;

#if defined(_DEBUG)
		default:
			assert(0);        // Unknown Data in DSB File !!!!!
			break;
#endif

		}
	}
}



/** - - - - - - - - - - - - - - - -	- - - - - - - - - - - - - - - - - - - - - - -
 * Read a dsc file and determine witch function to call to.
 * You have to open the dsc file by calling SNA_M_BeginReadFromDscFile
 * 
 * Input : Number of section to read. (big number (like 0xffff) = read all sections)
 */
void SNA_fn_vReadSectionFromDscFile( unsigned short _usNumberOfSection )
{
	unsigned long	ulVal;
	while( _usNumberOfSection-- )
	{
		ulVal= SNA_fn_ulTellWitchSectionInDscFile();
		switch( ulVal )
		{
		case SNA_C_ul_MemoryDescTitle :
			SNA_fn_vReadMemoryDescFromFile();
			break;

		case SNA_C_ul_LevelNameTitle :
			SNA_fn_vReadLevelNameFromFile();
			break;

		case SNA_C_ul_DirectoryDescTitle :
			SNA_fn_vReadDirectoriesDescFromFile();
			break;

		case SNA_C_ul_RandomDescTitle :
			SNA_fn_vReadRandomDescFromFile();
			break;

		case SNA_C_ul_VignetteDescTitle :
			SNA_fn_vReadVignetteDescFromFile();
			break;

		case SNA_C_ul_BigFileDescTitle :
			SNA_fn_vReadBigFileDescFromFile();
			break;

		case SNA_C_ul_LevelDscTitle :
			SNA_fn_vReadLevelDescFromFile();
			break;

		case SNA_C_ul_GameOptionDescTitle:
			SNA_fn_vReadDescGameOption();
			break;

		case SNA_C_ul_LevelDscLevelSoundBanks :
			SNA_fn_vReadLevelDescLevelSoundBanks();
			break;

		case SNA_C_ulEndOfDescSection :
			return;
			break;

#ifdef USE_IPT_DX5
		case SNA_C_ul_InitInputDeviceManager :
			{
				extern HINSTANCE fn_hGetApplicationInstance ( void ) ;
				extern HWND fn_hGetApplicationWindow ( void ) ;
				IPT_fn_vInitInput( ( short ) SNA_fn_lReadLongFromFile ( ) , fn_hGetApplicationInstance(),fn_hGetApplicationWindow(),(GLD_tdhDevice)0);
			}
			break ;

		case SNA_C_ul_ActivateDeviceTitle :
			SNA_fn_vReadActivateDevice();
			break;
#endif /* USE_IPT_DX5 */

		default:
#ifdef _DEBUG
			assert(0);  // Unknown section in a dsb file !!
#endif
			return;
		}
	}
}
