#include "ACP_Base.h" #include "ToolsCPA.h" #include "mmg.h" #include "SNA.h" #include "acp_opfi.h" #include "SNAFile.h" /* ANNECY OA - 13/07/99 { */ #define C_MAX_CONNECTED_FILES 20 char *a_BigFilesName[C_MAX_CONNECTED_FILES] = { "LEVELS.DAT", "MAP.DAT", "TEXTURES.DAT", "ANIMS.DAT", "DATA01.DAT", "DATA02.DAT", "DATA03.DAT", "DATA04.DAT", "DATA05.DAT", "DATA06.DAT" "DATA07.DAT", "DATA08.DAT", "DATA09.DAT", "DATA10.DAT", "DATA11.DAT", "DATA12.DAT", "DATA13.DAT", "DATA14.DAT", "DATA15.DAT", "DATA16.DAT", }; /* END ANNECY OA } */ /*------------------------------------------------------------------------*/ #define SNA_M_OffSet_Error 0xFFFFFFFF /*------------------------------------------------------------------------*/ unsigned char SNA_g_ucNextRelocationTableToLoad[4]; tdstRelocTable *SNA_g_PTCRelocationTable = NULL; DWORD SNA_g_a_dwInitKeyRelocationTableLoaded[SNA_M_ProtectRelocationTableSize]; DWORD SNA_g_a_dwProtectKeyRelocationTableLoaded[SNA_M_ProtectRelocationTableSize]; DWORD SNA_g_dwNumberOfRelocationTableLoaded; /* * * */ void SNA_fn_vInitBigFile(); ACP_tdxBool SNA_fn_bGetHandleToRelocationTableInBigFile( SNA_tdstFile *_p_stFile ); /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ HANDLE SNA_fn_hGetOffSetInBigFileWithSinusHeader(DWORD *p_dwOffSet); #define M_SECTOR_SIZE 2048 DWORD SNA_g_dwNumberOfOccur; DWORD SNA_g_dwFirstHeaderSize; DWORD SNA_g_dwHeaderSize; DWORD SNA_g_dwTotalSector; DWORD SNA_g_dwConnectedFiles; /*------------------------------------------------------------------------*/ #pragma warning( disable : 4102 ) // Disable warning messages : unreferenced label /* * Function to convert a relocation table file number + file type to a real file handle. * This is version without protection bigfile. */ #include "GAM\structur\engmode.h" ACP_tdxBool SNA_fn_bGetHandleToRelocationTable( SNA_tdstFile *_p_stFile ) { char szFileName[256]; char *p_szLevelName, *p_cSubMapDelimiter; /* ------------------------------------------ */ /* to get begin and end addresses of function */ #ifdef PTC_SYSTEM_ACTIVED if (PTC_g_bTakeAddresses) { PTC_M_AddFunctionCheckSum(0,SNA_fn_bGetHandleToRelocationTable); return TRUE; } #endif /* ------------------------------------------ */ /* ------------------------------------------ */ PTC_M_DeclareBeginLabel(SNA_fn_bGetHandleToRelocationTable) /* Loading fix ? */ if( SNA_g_ucNextRelocationTableToLoad[0] == 255 ) { /* ANNECY OA - 20/07/99 { */ #ifdef RETAIL sprintf( szFileName, "%c:\\%s\\Fix", g_cCDROM, fn_szGetLevelsDataPath() ); #else sprintf( szFileName, "%s\\Fix", fn_szGetLevelsDataPath() ); #endif /* END ANNECY OA } */ } else { #ifdef DEBUG /* Trying to load a level that does not exist ? */ assert( SNA_g_ucNextRelocationTableToLoad[0] < g_stEngineStructure.ucNumberOfLevels ); #endif /* ANNECY MT - 30/03/99 { Pc Protection */ /* Trying to load rt? file into BigFile */ if (SNA_fn_bBigFileUsed ()) { if (SNA_fn_bGetHandleToRelocationTableInBigFile (_p_stFile)) return TRUE; } /* END ANNECY MT } */ /* Get level name from its number */ p_szLevelName = g_stEngineStructure.a_szLevelName[SNA_g_ucNextRelocationTableToLoad[0]]; if( (p_cSubMapDelimiter = strchr( p_szLevelName, '$' )) != NULL ) *p_cSubMapDelimiter = 0; /* Compute full level name (with path) */ /* ANNECY OA - 20/07/99 { */ #ifdef RETAIL sprintf( szFileName, "%c:\\%s\\%s\\%s", g_cCDROM, fn_szGetLevelsDataPath(), p_szLevelName, p_szLevelName ); #else sprintf( szFileName, "%s\\%s\\%s", fn_szGetLevelsDataPath(), p_szLevelName, p_szLevelName ); #endif /* END ANNECY OA } */ if( p_cSubMapDelimiter ) *p_cSubMapDelimiter = '$'; } /* add file extension (given its type) */ switch( SNA_g_ucNextRelocationTableToLoad[1] ) { case SNA_C_ucSNARelocationTable: strcat( szFileName, ".rtb" ); break; case SNA_C_ucGlobalPointersRelocationTable: strcat( szFileName, ".rtp" ); break; case SNA_C_ucTexturesRelocationTable: strcat( szFileName, ".rtt" ); break; case SNA_C_ucSoundRelocationTable: strcat( szFileName, ".rts" ); break; case SNA_C_ucLipsSyncRelocationTable: strcat( szFileName, ".rtl" ); break; #ifdef DEBUG /* Unknown relocation file type */ default: assert(0); #endif } PTC_M_DeclareEndLabel(SNA_fn_bGetHandleToRelocationTable) /* Open it and returns handle. */ /* ANNECY OA - 20/07/99 { */ { BOOL returnValue = SNA_fn_bFOpen( szFileName, SNA_C_ucRead, 0, _p_stFile ); #ifdef RETAIL while (returnValue == FALSE) { if (MessageBox(NULL, "Inserez le CD dans le lecteur", "CDROM non trouvé!", MB_RETRYCANCEL) == IDCANCEL) { abort(); } returnValue = SNA_fn_bFOpen( szFileName, SNA_C_ucRead, 0, _p_stFile ); } #endif return returnValue; /*return SNA_fn_bFOpen( szFileName, SNA_C_ucRead, 0, _p_stFile );*/ } /* END ANNECY OA } */ } /* Return the position of a level name in global array of level names. */ unsigned char SNA_fn_ucGetLevelID( char *_p_szLevelName ) { unsigned int i = g_stEngineStructure.ucNumberOfLevels; unsigned iLength = strlen( _p_szLevelName ); while( i-- ) { if( strnicmp( _p_szLevelName, g_stEngineStructure.a_szLevelName[i], iLength ) == 0 ) return i; } #ifndef RETAIL // We did not find the level in list of level => the program will crash. so.... { FILE *hFile = fopen( "test.log", "at" ); if( hFile ) { fprintf( hFile, "Can't change to map '%s': not found in map list\n", _p_szLevelName ); fclose( hFile ); exit( 1 ); } } assert(0); #endif return (unsigned char)-1; } /** * SNA_fn_pLoadRelocationTable : * Read one .rt? file containing a relocation table. */ tdstRelocTable *SNA_fn_pLoadRelocationTable() { SNA_tdstFile stFile; unsigned char ucModule=0xf0,ucBloc=0xf0,ucNbOfBloc,i,ucOldModule=0xf0,ucOldBloc=0xf0; unsigned long ulSize/*,j*/; tdstRelocTable *p_stRelocTable; tdstBloc *p_stBloc; tdstPtr *p_stPtr; SNA_fn_vInitArrays(); if( ! SNA_fn_bGetHandleToRelocationTable( &stFile ) ) return 0; SNA_fn_ulFRead( &ucNbOfBloc , sizeof(char), 1, &stFile ); p_stRelocTable=(tdstRelocTable *)malloc(sizeof(tdstRelocTable)); p_stRelocTable->ucBlocNumber=ucNbOfBloc; p_stBloc=(tdstBloc *)malloc(sizeof(tdstBloc)*ucNbOfBloc); p_stRelocTable->p_stBloc=p_stBloc; for(i=0;iucBlocNumber--; break; } SNA_fn_ulFRead( &ulSize , sizeof(long), 1, &stFile ); if( ulSize != 0L ) { p_stPtr=(tdstPtr *)malloc(sizeof(tdstPtr)*ulSize); /* for(j=0;jp_stBloc; for(i=0;iucBlocNumber;i++) { free(p_stBloc[i].p_stPtr); } free(p_stBloc); free(p_stRelocTable); } } /* ANNECY MT - 30/03/99 { PC Protection */ /*------------------------------------------------------------------------ * * Author Marc Trabucato * Date 31 mars 1999 * * Prototype SNA_fn_vInitBigFile * Return Type void * * Description * *------------------------------------------------------------------------*/ void SNA_fn_vInitBigFile() { if(SNA_fn_bBigFileUsed ()) { char szBigFileName[MAX_PATH]; HANDLE hFile; /* ANNECY OA - 13/07/99 { */ #ifdef RETAIL sprintf (szBigFileName , "%c:\\%s\\%s", g_cCDROM, fn_szGetLevelsDataPath(), a_BigFilesName[0]); #else sprintf (szBigFileName , "%s\\%s", fn_szGetLevelsDataPath(), a_BigFilesName[0]); #endif /*sprintf (szBigFileName , "%s\\data.000", fn_szGetLevelsDataPath());*/ /* END ANNECY OA } */ hFile = PTC_CreateFile (szBigFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); /* ANNECY OA - 20/07/99 { */ #ifdef RETAIL while (hFile == INVALID_HANDLE_VALUE) { if (MessageBox(NULL, "Inserez le CD dans le lecteur", "CDROM non trouvé!", MB_RETRYCANCEL) == IDCANCEL) { abort(); } hFile = PTC_CreateFile (szBigFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); } #endif /* END ANNECY OA } */ if (hFile != INVALID_HANDLE_VALUE) { DWORD dwKeys[4]; DWORD dwRead; DWORD dwValue , dwUnused; /* read keys */ PTC_ReadFile (hFile , dwKeys , 4 * sizeof(DWORD) , &dwRead , NULL); /* read Number of map */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); dwUnused = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; /* read Number of Occur */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); SNA_g_dwNumberOfOccur = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; /* read Header Step */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); dwUnused = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; /* read First Header Size */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); SNA_g_dwFirstHeaderSize = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; /* read File Step */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); dwUnused = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; /* read Sector Size */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); SNA_g_dwHeaderSize = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; /* read Number of Sectors */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); SNA_g_dwTotalSector = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; /* read Number of Connected Files */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); SNA_g_dwConnectedFiles = (dwValue - dwKeys[0]) ^ dwKeys[1]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; PTC_CloseHandle (hFile); } } } /*------------------------------------------------------------------------ * * Author Marc Trabucato * Date 31 mars 1999 * * Prototype SNA_fn_bGetHandleToRelocationTableInBigFile * Parameters _p_stFile : * Return Type ACP_tdxBool * * Description Read rt? files into bigfile for each map * *------------------------------------------------------------------------*/ ACP_tdxBool SNA_fn_bGetHandleToRelocationTableInBigFile( SNA_tdstFile *_p_stFile ) { DWORD dwOffSet; DWORD dwProtectKey; HANDLE hFile; /* ------------------------------------------ */ /* to get begin and end addresses of function */ #ifdef PTC_SYSTEM_ACTIVED if (PTC_g_bTakeAddresses) { PTC_M_AddFunctionCheckSum(1,SNA_fn_bGetHandleToRelocationTableInBigFile); return TRUE; } #endif /* ------------------------------------------ */ /* ------------------------------------------ */ PTC_M_DeclareBeginLabel(SNA_fn_bGetHandleToRelocationTableInBigFile) hFile = SNA_fn_hGetOffSetInBigFileWithSinusHeader (&dwOffSet); if (hFile != INVALID_HANDLE_VALUE) { /* seek */ PTC_SetFilePointer (hFile , dwOffSet , NULL , FILE_BEGIN); /* uses encryption */ SNA_fn_vInitFile (SNA_C_ucUseEncryption , _p_stFile); // compute crypt key */* SNA_g_ucNextRelocationTableToLoad[3] = ~SNA_g_ucNextRelocationTableToLoad[2]; _p_stFile -> ulCryptKey = SNA_fn_dwGetCryptKeyRelocationTable(); SNA_g_a_dwInitKeyRelocationTableLoaded [SNA_g_dwNumberOfRelocationTableLoaded] = *((DWORD*)SNA_g_ucNextRelocationTableToLoad); _p_stFile -> hFile = hFile; _p_stFile -> bReadSuccess = TRUE; /* read protect-key */ SNA_fn_ulFRead (&dwProtectKey , 4 , 1 , _p_stFile); SNA_g_a_dwProtectKeyRelocationTableLoaded [SNA_g_dwNumberOfRelocationTableLoaded++] = dwProtectKey; SNA_M_vUpdateOccurrenceToLoad(); return TRUE; } PTC_M_DeclareEndLabel(SNA_fn_bGetHandleToRelocationTableInBigFile) return FALSE; } /*------------------------------------------------------------------------ * * Author Marc Trabucato * Date 31 mars 1999 * * Prototype SNA_fn_dwGetOffSetInBigFileWithSinusHeader * Return Type DWORD * * Description each occurence has it's own header in the file * Headers are placed int the file using a recurent serie *------------------------------------------------------------------------*/ HANDLE SNA_fn_hGetOffSetInBigFileWithSinusHeader(DWORD *p_dwOffSet) { char szBigFileName[MAX_PATH]; HANDLE hFile; /* ANNECY OA - 13/07/99 { */ #ifdef RETAIL sprintf (szBigFileName , "%c:\\%s\\%s", g_cCDROM, fn_szGetLevelsDataPath(), a_BigFilesName[0]); #else sprintf (szBigFileName , "%s\\%s", fn_szGetLevelsDataPath(), a_BigFilesName[0]); #endif /*sprintf (szBigFileName , "%s\\data.000", fn_szGetLevelsDataPath());*/ /* END ANNECY OA } */ hFile = PTC_CreateFile (szBigFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); /* ANNECY OA - 20/07/99 { */ #ifdef RETAIL while (hFile == INVALID_HANDLE_VALUE) { if (MessageBox(NULL, "Inserez le CD dans le lecteur", "CDROM non trouvé!", MB_RETRYCANCEL) == IDCANCEL) { abort(); } hFile = PTC_CreateFile (szBigFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); } #endif /* END ANNECY OA } */ if (hFile != INVALID_HANDLE_VALUE) { DWORD dwFile , dwOccur , dwOffSetHeader; DWORD dwKeys[4]; DWORD dwRead; DWORD dwValue; DWORD dwCount; DWORD dwN; double fN , fValue , fA , fB , fC, fInteger; // Compute Occur and File dwFile = SNA_g_ucNextRelocationTableToLoad[0] * 4; switch( SNA_g_ucNextRelocationTableToLoad[1] ) { case SNA_C_ucSNARelocationTable: break; case SNA_C_ucGlobalPointersRelocationTable: dwFile += 1; break; case SNA_C_ucSoundRelocationTable: dwFile += 2; break; case SNA_C_ucTexturesRelocationTable: dwFile += 3; break; #ifdef DEBUG case SNA_C_ucLipsSyncRelocationTable: default: assert(0); #endif } dwOccur = (SNA_g_ucNextRelocationTableToLoad[2]) % SNA_g_dwNumberOfOccur; SNA_g_ucNextRelocationTableToLoad[2] = (unsigned char) (dwOccur & 0x000000FF); // seek wanted header fA = 0.69314; fB = 1.69314; fC = 0.52658; fN = 1.06913; for (dwN = 0 ; dwN < dwOccur ; dwN++) { fN = fN + fA * fabs(sin(fB * dwN * dwN)) + fC; //fN = floor(fN * 1000000.0) / 1000000.0; } fValue = floor(modf(fN , &fInteger) * 1000000.0) / 1000000.0; dwOffSetHeader = SNA_g_dwHeaderSize * (DWORD)floor(fValue * SNA_g_dwTotalSector) + SNA_g_dwFirstHeaderSize; PTC_SetFilePointer (hFile , dwOffSetHeader , NULL , FILE_BEGIN); // read crypt key PTC_ReadFile (hFile , dwKeys , 4 * sizeof(DWORD) , &dwRead , NULL); // seek wanted file for (dwCount = 0 ; dwCount < dwFile ; dwCount++) { dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; } PTC_SetFilePointer (hFile , dwFile * 4 , NULL , FILE_CURRENT); /* read OffSet */ PTC_ReadFile (hFile , &dwValue , 4 , &dwRead , NULL); *p_dwOffSet = (dwValue - dwKeys[0]) ^ dwKeys[1]; /* ANNECY OA - 15/07/99 { */ /* Multi files managment */ { char sBuffer[512]; char nbuffer[512]; long lSectorOffset = SNA_g_dwTotalSector / SNA_g_dwConnectedFiles; long lByteOffset = lSectorOffset*M_SECTOR_SIZE; long lHigherFileNumber = *p_dwOffSet / lByteOffset; long lFileToOpen = PTC_fn_lGetRandomRange(0, lHigherFileNumber); PTC_SetFilePointer (hFile , *p_dwOffSet , NULL , FILE_BEGIN); PTC_ReadFile (hFile , sBuffer , 512 * sizeof(char) , &dwRead , NULL); *p_dwOffSet -= lFileToOpen*lByteOffset; PTC_CloseHandle(hFile); /* ANNECY OA - 20/07/99 { */ #ifdef RETAIL sprintf (szBigFileName , "%c:\\%s\\%s", g_cCDROM, fn_szGetLevelsDataPath(), a_BigFilesName[lFileToOpen]); #else sprintf (szBigFileName , "%s\\%s", fn_szGetLevelsDataPath(), a_BigFilesName[lFileToOpen]); #endif /* END ANNECY OA } */ hFile = PTC_CreateFile (szBigFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); /* ANNECY OA - 20/07/99 { */ #ifdef RETAIL while (hFile == INVALID_HANDLE_VALUE) { if (MessageBox(NULL, "Inserez le CD dans le lecteur", "CDROM non trouvé!", MB_RETRYCANCEL) == IDCANCEL) { abort(); } hFile = PTC_CreateFile (szBigFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); } #endif /* END ANNECY OA } */ PTC_SetFilePointer (hFile , *p_dwOffSet , NULL , FILE_BEGIN); PTC_ReadFile (hFile , nbuffer , 512 * sizeof(char) , &dwRead , NULL); } /* END ANNECY OA } */ } return hFile; } /* END ANNECY MT } */ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/