/*=========================================================================
* Snapoint.c : Save & Read the sound pointers
*
* Version              1.0
* Creation date        03/09/97
* Revision date
*
* (c) Ubi R&D 1997
*=======================================================================*/

#include "ACP_Base.h"
#include "mmg.h"

#include "ToolsCPA.h"

#include "Actions/AllActs.h"
#include "structur/Objects.h"
#include "ObjType.h"
#include "SNA.h"
#include "acp_opfi.h"
#include "SNAfile.h"

struct SNA_tdstFixInfo_ SNA_g_stFixInfo =
{
	NULL,NULL,NULL,NULL, 0,
	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};

HANDLE                  g_hPointersFile;
struct tdstPtr_         *g_p_stNextPtrRelocInfo;          // Next pointer to use in pointer table relocation
struct tdstPtr_         *g_p_stAfterLastPtrRelocInfo;     // Pointer after last pointer in pointer table relocation

/*-----------------------------------------------------------------------------
 *  Description : Open pointers file (write)
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : Michaël
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_xWriteOpenGlobalPointersFile(char *szFileName)
{
	DWORD dwAttrib = GetFileAttributes(szFileName);

	SNA_fn_vInitArrays();		// MR2711

	// CGHT 1612

	if(dwAttrib & FILE_ATTRIBUTE_READONLY)
		SetFileAttributes(szFileName , dwAttrib & ~FILE_ATTRIBUTE_READONLY);

	ACP_M_OPENFILE(SNA_M_CREATEFILE,g_hPointersFile,INVALID_HANDLE_VALUE,szFileName,(szFileName , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL , NULL));
}

/*-----------------------------------------------------------------------------
 *  Description : Open pointers file (read)
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : Michaël
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_xReadOpenGlobalPointersFile(char *szFileName)
{

	SNA_fn_vInitArrays();

    ACP_M_OPENFILE(SNA_M_CREATEFILE,g_hPointersFile,INVALID_HANDLE_VALUE,szFileName,(szFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL));


	SNA_M_LoadUsedRelocationTable();

	g_p_stNextPtrRelocInfo = &SNA_g_PTCRelocationTable->p_stBloc[0].p_stPtr[0];
	g_p_stAfterLastPtrRelocInfo = &SNA_g_PTCRelocationTable->p_stBloc[0].p_stPtr[SNA_g_PTCRelocationTable->p_stBloc[0].ulSize];

	// Take care of the progress bar
	VIG_fn_vAddToProgressBar(1);

}


/*-----------------------------------------------------------------------------
 *  Description : Close pointers file
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : Michaël
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vCloseGlobalPointersFile()
{
	SNA_M_FreeRelocationTable();
    SNA_M_CLOSEHANDLE(g_hPointersFile);

	// Take care of the progress bar
	VIG_fn_vAddToProgressBar(1);
	g_p_stNextPtrRelocInfo = g_p_stAfterLastPtrRelocInfo = NULL;
}

/*-----------------------------------------------------------------------------
 *  Description : Open Texture Relocation file (read)
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : CGHT
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_xReadOpenGlobalTextureFile()
{
	SNA_M_LoadUsedRelocationTable();
	g_p_stNextPtrRelocInfo = &SNA_g_PTCRelocationTable->p_stBloc[0].p_stPtr[0];
	g_p_stAfterLastPtrRelocInfo = &SNA_g_PTCRelocationTable->p_stBloc[0].p_stPtr[SNA_g_PTCRelocationTable->p_stBloc[0].ulSize];
}

/*-----------------------------------------------------------------------------
 *  Description : Close Texture Relocation file
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : CGHT
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vCloseGlobalTextureFile()
{
	SNA_M_FreeRelocationTable();
	g_p_stNextPtrRelocInfo = g_p_stAfterLastPtrRelocInfo = NULL;
}

/*-----------------------------------------------------------------------------
 *  Description : Write any block in file
 *-----------------------------------------------------------------------------
 *  Input :         Address and Size of block
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 09/02/99             Author : MT
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vWriteBlockInGlobalPointersFile(void *p_vAdr,unsigned long ulStructSize)
{
    DWORD dwBytesWritten;

    SNA_M_WRITEFILE(g_hPointersFile , p_vAdr, ulStructSize , &dwBytesWritten, NULL);
}

/*-----------------------------------------------------------------------------
 *  Description : Read any block in file
 *-----------------------------------------------------------------------------
 *  Input :         Address and Size of block
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 09/02/99            Author : MT
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vReadBlockInGlobalPointersFile(void *p_vAdr,unsigned long ulStructSize)
{
    DWORD dwBytesRead;

    SNA_M_READFILE(g_hPointersFile , p_vAdr, ulStructSize , &dwBytesRead, NULL);
}

/*-----------------------------------------------------------------------------
 *  Description : Write a pointer in file
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : Michaël
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vWritePointerInGlobalPointersFile(unsigned long ulPointerAdr)
{
    SNA_fn_vWriteBlockInGlobalPointersFile(&ulPointerAdr,4);
}

void SNA_fn_vWriteStructureInGlobalPointersFile(void *p_vAdr,unsigned long ulStructSize)
{
    SNA_fn_vWriteBlockInGlobalPointersFile(p_vAdr,ulStructSize);

	// GuS (22/09/98) for 32 bits alignement.
	if( (ulStructSize%4) != 0 )
	{
		char a3_cDummy[3];
		memset( a3_cDummy, 0, 3 );
        SNA_fn_vWriteBlockInGlobalPointersFile(a3_cDummy,4-(ulStructSize%4));
	}
}


/*-----------------------------------------------------------------------------
 *  Description : Writes an array to global pointer file.
 *                This function makes sure that each element of the array is 32 bits aligned.
 *-----------------------------------------------------------------------------
 *  Input :         Base address of array, size of an element, number of elements
 *                  Ex: struct tdstDummyStruct_ a24_stArray[24];
 *                  SNA_fn_vWriteArrayInGlobalPointersFile
 *                       ( a24_stArray, sizeof(struct tdstDummyStruct_), 24 );
 *
 *  Output :        None
 *  Remarks :       Use this function if your array contains pointers.
 *                  Otherwise, use SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile
 *-----------------------------------------------------------------------------
 *  Creation date : 22/09/98            Author : Guillaume Souchet
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vWriteArrayInGlobalPointersFile
	(
		void *p_vAdr,
		unsigned long ulNumberOfElements,
		unsigned long ulElementSize
	)
{
	unsigned long ulRest;            // Number of bytes to add for 32 bits align.
	char a3_cDummy[3];               // Array of bytes to write for 32 bits align.


	// Proceed only for element size > 0
	if( ulElementSize == 0 ) return;

	// Initialise variables
	memset( a3_cDummy, 0, 3 );
	if( (ulRest = (ulElementSize & 0x03)) != 0 )
		ulRest = 4-ulRest;

	// Write all elements.
	while( ulNumberOfElements-- )
	{
		// Write one element and make it 32 bits aligned.
        SNA_fn_vWriteBlockInGlobalPointersFile (p_vAdr , ulElementSize);
        SNA_fn_vWriteBlockInGlobalPointersFile (a3_cDummy , ulRest);

        // Go to next element.
		p_vAdr = (void *)(((char *)p_vAdr)+ulElementSize);
	}
}


/*-----------------------------------------------------------------------------
 *  Description : Function for writing an array *WITHOUT POINTERS* to global pointer file.
 *                This function don't care if all elements are 32 bits aligned.
 *-----------------------------------------------------------------------------
 *  Input :         Base address of array, size of an element, number of elements
 *                  Ex: struct tdstDummyStruct_ a24_stArray[24];
 *                  SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile(
 *                      a24_stArray, sizeof(struct tdstDummyStruct_), 24 );
 *  Output :        None
 *  Remark :        Use this function if your array do *NOT* contains pointers.
                    Otherwise, use SNA_fn_vWriteArrayInGlobalPointersFile
 *-----------------------------------------------------------------------------
 *  Creation date : 22/09/98            Author : Guillaume Souchet
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile
		(
			void *p_vAdr,
			unsigned long ulNumberOfElements,
			unsigned long ulElementSize
		)
{
	unsigned long ulRest;            // Number of bytes to add for 32 bits align.
	char a3_cDummy[3];               // Array of bytes to write for 32 bits align.
	unsigned long ulTotalSize = ulElementSize * ulNumberOfElements;


	// Proceed only if there's something to write.
	if( ulTotalSize == 0 ) return;

	// Initialise variables
	memset( a3_cDummy, 0, 3 );
	if( (ulRest = (ulTotalSize & 0x03)) != 0 )
		ulRest = 4-ulRest;

	// Write all elements.
    SNA_fn_vWriteBlockInGlobalPointersFile (p_vAdr , ulTotalSize);
	// Write some bytes for 32 bits alignement
    SNA_fn_vWriteBlockInGlobalPointersFile (a3_cDummy , ulRest);
}


/*-----------------------------------------------------------------------------
 *  Description : Read a pointer
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : Michaël
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
unsigned long SNA_fn_vReadPointerFromGlobalPointersFile()
{
	unsigned long	ulOldAdrPointer;

    SNA_fn_vReadBlockInGlobalPointersFile (&ulOldAdrPointer , 4);

	if(   g_p_stNextPtrRelocInfo < g_p_stAfterLastPtrRelocInfo 
	   && ulOldAdrPointer == g_p_stNextPtrRelocInfo->p_vPtr )
	{
		unsigned char ucModuleNumber = g_p_stNextPtrRelocInfo -> ucTargetModule;
		unsigned char ucBlocNumber = g_p_stNextPtrRelocInfo -> ucTargetBlock;
		if( g_a_bIsBlocRelocated[ucModuleNumber][ucBlocNumber] )
			ulOldAdrPointer+=g_a_ulOffset[ucModuleNumber][ucBlocNumber];

		g_p_stNextPtrRelocInfo++;
	}
	else
	{
		ulOldAdrPointer = ulOldAdrPointer;
	}

	return ulOldAdrPointer;
}

/*-----------------------------------------------------------------------------
 *  Description : Relocate Texture pointer
 *-----------------------------------------------------------------------------
 *  Input :         Name of the file
 *  Output :        None
 *-----------------------------------------------------------------------------
 *  Creation date : 03/09/97            Author : CGHT
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vRelocateTexturePointer(unsigned long **p_ulOldAdrPointer)
{
/*  unsigned long		ulSize;
  struct tdstPtr_	*p_stPtrTemp, *p_stPtrEnd;

  ulSize = SNA_g_PTCRelocationTable->p_stBloc[0].ulSize;

  p_stPtrTemp = &SNA_g_PTCRelocationTable->p_stBloc[0].p_stPtr[0];
  p_stPtrEnd = &SNA_g_PTCRelocationTable->p_stBloc[0].p_stPtr[ulSize];

	while (p_stPtrTemp < p_stPtrEnd)
	{
		unsigned char ucModuleNumber,ucBlocNumber;

		ucModuleNumber = p_stPtrTemp -> ucTargetModule;
		ucBlocNumber = p_stPtrTemp -> ucTargetBlock;

		if ((*(unsigned long *)p_ulOldAdrPointer==p_stPtrTemp->p_vPtr)&&(g_a_bIsBlocRelocated[ucModuleNumber][ucBlocNumber]))
		{
			((unsigned long)*p_ulOldAdrPointer)+=g_a_ulOffset[ucModuleNumber][ucBlocNumber];
			break;
		}
		p_stPtrTemp ++;
	}
*/
	if(   g_p_stNextPtrRelocInfo < g_p_stAfterLastPtrRelocInfo 
	   && *p_ulOldAdrPointer == (unsigned long *)g_p_stNextPtrRelocInfo->p_vPtr )
	{
		unsigned char ucModuleNumber = g_p_stNextPtrRelocInfo -> ucTargetModule;
		unsigned char ucBlocNumber = g_p_stNextPtrRelocInfo -> ucTargetBlock;
		if( g_a_bIsBlocRelocated[ucModuleNumber][ucBlocNumber] )
			*(unsigned long *)p_ulOldAdrPointer += g_a_ulOffset[ucModuleNumber][ucBlocNumber];

		g_p_stNextPtrRelocInfo++;
	}

}

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

void SNA_fn_vReadStructureFromGlobalPointersFile(unsigned long *p_ulAdr,unsigned long ulStructSize)
{
//  unsigned long		i,j;
  unsigned long		*p_ulAdrTemp, *p_ulAdrEnd;

    SNA_fn_vReadBlockInGlobalPointersFile (p_ulAdr , ulStructSize);

	// Read trailing bytes for 32 bits alignement
	if( (ulStructSize%4) != 0 )
	{
		char a3_cDummy[3];
        SNA_fn_vReadBlockInGlobalPointersFile (a3_cDummy , 4-(ulStructSize%4));
	}


	p_ulAdrTemp = p_ulAdr;
	ulStructSize>>=2;

	p_ulAdrEnd = &p_ulAdr[ulStructSize];

	while (p_ulAdrTemp < p_ulAdrEnd)
	{
		if(    g_p_stNextPtrRelocInfo < g_p_stAfterLastPtrRelocInfo 
		    && *p_ulAdrTemp == g_p_stNextPtrRelocInfo->p_vPtr )
		{
			unsigned char ucModuleNumber = g_p_stNextPtrRelocInfo -> ucTargetModule;
			unsigned char ucBlocNumber = g_p_stNextPtrRelocInfo -> ucTargetBlock;
			if( g_a_bIsBlocRelocated[ucModuleNumber][ucBlocNumber] )
				*p_ulAdrTemp += g_a_ulOffset[ucModuleNumber][ucBlocNumber];

			g_p_stNextPtrRelocInfo++;
		}
		else
		{
			*p_ulAdrTemp = *p_ulAdrTemp;
		}
		p_ulAdrTemp ++;
	}
}

// MR1311
void SNA_fn_vSimpleReadFromGlobalPointersFile(unsigned long *p_ulAdr,unsigned long ulStructSize)
{
    SNA_fn_vReadBlockInGlobalPointersFile (p_ulAdr , ulStructSize);
}


/*-----------------------------------------------------------------------------
 *  Description : Reads an array from global pointer file.
 *-----------------------------------------------------------------------------
 *  Input :         Base address of array, size of an element, number of elements
 *                  Ex: struct tdstDummyStruct_ a24_p_stArray[24];
 *                  SNA_fn_vReadArrayFromGlobalPointersFile
 *                       ( a24_p_stArray, sizeof(struct tdstDummyStruct_), 24 );
 *
 *  Output :        None
 *  Remarks :       see SNA_fn_vWriteArrayInGlobalPointersFile
 *-----------------------------------------------------------------------------
 *  Creation date : 22/09/98            Author : Guillaume Souchet
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vReadArrayFromGlobalPointersFile
	(
		void *p_vAdr,
		unsigned long ulNumberOfElements,
		unsigned long ulElementSize
	)
{
	// Proceed only for element size > 0
	if( ulElementSize == 0 || ulNumberOfElements == 0 ) return;

	// Read all elements.
	while( ulNumberOfElements-- )
	{
		SNA_fn_vReadStructureFromGlobalPointersFile( p_vAdr, ulElementSize );

		// Go to next element.
		p_vAdr = (void *)(((char *)p_vAdr)+ulElementSize);
	}
}


/*-----------------------------------------------------------------------------
 *  Description : Function for reading an array *CONTAINING NO POINTERS* from global pointer file.
 *-----------------------------------------------------------------------------
 *  Input :         Base address of array, size of an element, number of elements
 *                  Ex: struct tdstDummyStruct_ a24_stArray[24];
 *                  SNA_fn_vWriteArrayInGlobalPointersFile(
 *                      a24_stArray, sizeof(struct tdstDummyStruct_), 24 );
 *  Output :        None
 *  Remark :        Use this function if your array do *NOT* contains pointers.
                    Otherwise, use SNA_fn_vWriteArrayInGlobalPointersFile
 *-----------------------------------------------------------------------------
 *  Creation date : 22/09/98            Author : Guillaume Souchet
 *-----------------------------------------------------------------------------
 *  Modification date :			        Modification Author :
 *  Modifications :
 *---------------------------------------------------------------------------*/
void SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile
	(
		void *p_vAdr,
		unsigned long ulNumberOfElements,
		unsigned long ulElementSize
	)
{
	unsigned long ulRest;            // Number of bytes to add for 32 bits align.
	char a3_cDummy[3];               // Array of bytes to write for 32 bits align.
	unsigned long ulTotalSize = ulElementSize * ulNumberOfElements;


	// Proceed only if there's something to write.
	if( ulTotalSize == 0 ) return;

	// Initialise variables
	memset( a3_cDummy, 0, 3 );
	if( (ulRest = (ulTotalSize & 0x03)) != 0 )
		ulRest = 4-ulRest;


	// Read all elements.
    SNA_fn_vReadBlockInGlobalPointersFile (p_vAdr , ulTotalSize);
    SNA_fn_vReadBlockInGlobalPointersFile (a3_cDummy , ulRest);
}
