#include #include #include #include #include #include "adeline.h" #include "lib_sys.h" #include "\projet\lib386\lib_samp\lib_wave.h" #define RECOVER_AREA 500 /*══════════════════════════════════════════════════════════════════════════* █ █ █▀▀▀█ █▀▀▀█ █▀▀▀▀ ██▀▀▀ ██▀▀▀ █▀▀▀█ █ █ █▀▀▀█ █▀▀▀▀ █▀▀▀▀ ██▀▀█ ██ ▄█ ██▀█▀ ██▀▀ ▀▀▀▀█ ▀▀▀▀█ ██ █ ██ █ ██▀█▀ ██ ██▀▀ ▀▀ ▀ ▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ *══════════════════════════════════════════════════════════════════════════*/ /*──────────────────────────────────────────────────────────────────────────*/ WORD HQR_Flag = FALSE ; typedef struct { ULONG SizeFile ; ULONG CompressedSizeFile ; WORD CompressMethod ; /* 0 stored */ /* 1 LZS */ } T_HEADER ; void Expand( void *ptrsourcecomp, void *ptrblocdest, ULONG sizefile ) ; /*══════════════════════════════════════════════════════════════════════════* █ █ █▀▀▀█ █▀▀▀█ █ █▀▀▀█ █▀▀▀█ █▀▀▀▄ ██▀▀█ ██ ▄█ ██▀█▀ ██ ██ █ ██▀▀█ ██ █ ▀▀ ▀ ▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀ *══════════════════════════════════════════════════════════════════════════*/ /*──────────────────────────────────────────────────────────────────────────*/ void *LoadMalloc_HQR( UBYTE *name, UWORD index ) { LONG handle ; UWORD nbbloc ; ULONG buffer ; ULONG seekindex ; UBYTE *ptrbloc ; UBYTE *ptrdecomp ; T_HEADER header ; handle = OpenRead( name ) ; if( !handle ) return 0L ; Read( handle, &buffer, 4L ) ; nbbloc = (UWORD)(buffer / 4L) ; if( index >= nbbloc ) { Close( handle ) ; return 0L ; } Seek( handle, index * 4L, SEEK_START ) ; Read( handle, &seekindex, 4L ) ; Seek( handle, seekindex, SEEK_START ) ; Read( handle, &header, sizeof( header ) ) ; ptrbloc = Malloc( header.SizeFile + RECOVER_AREA ) ; if( !ptrbloc ) { Close( handle ) ; return 0L ; } switch( header.CompressMethod ) { case 0: /* Stored */ Read( handle, ptrbloc, header.SizeFile ) ; break ; case 1: /* LZS */ ptrdecomp = ptrbloc + header.SizeFile - header.CompressedSizeFile + RECOVER_AREA ; Read( handle, ptrdecomp, header.CompressedSizeFile ) ; Expand( ptrdecomp, ptrbloc, header.SizeFile ) ; break ; default: Free( ptrbloc ) ; Close( handle ) ; return 0L ; /* UnKnown version */ } Mshrink( ptrbloc, header.SizeFile ) ; Close( handle ) ; return ptrbloc ; } /*──────────────────────────────────────────────────────────────────────────*/ ULONG Load_HQR( UBYTE *name, void *ptrdest, UWORD index ) { LONG handle ; UWORD nbbloc ; ULONG buffer ; ULONG seekindex ; UBYTE *ptrdecomp ; T_HEADER header ; handle = OpenRead( name ) ; if( !handle ) return 0L ; Read( handle, &buffer, 4L ) ; nbbloc = (UWORD)(buffer / 4L) ; if( index >= nbbloc ) { Close( handle ) ; return 0L ; } Seek( handle, index * 4L, SEEK_START ) ; Read( handle, &seekindex, 4L ) ; Seek( handle, seekindex, SEEK_START ) ; Read( handle, &header, sizeof( header ) ) ; switch( header.CompressMethod ) { case 0: /* Stored */ Read( handle, ptrdest, header.SizeFile ) ; break ; case 1: /* LZS */ ptrdecomp = (UBYTE*)ptrdest + header.SizeFile - header.CompressedSizeFile + RECOVER_AREA ; Read( handle, ptrdecomp, header.CompressedSizeFile ) ; Expand( ptrdecomp, ptrdest, header.SizeFile ) ; break ; default: Close( handle ) ; return 0L ; /* UnKnown version */ } Close( handle ) ; return header.SizeFile ; } /*──────────────────────────────────────────────────────────────────────────*/ ULONG Size_HQR( char *name, UWORD index ) { ULONG handle ; UWORD nbbloc ; ULONG buffer ; ULONG seekindex ; UBYTE *ptrdecomp ; T_HEADER header ; handle = OpenRead( name ) ; if( !handle ) return 0 ; Read( handle, &buffer, 4 ) ; nbbloc = (UWORD)(buffer / 4) ; if( index >= nbbloc ) { Close( handle ) ; return 0 ; } Seek( handle, index * 4, SEEK_START ) ; Read( handle, &seekindex, 4 ) ; if( seekindex ) { Seek( handle, seekindex, SEEK_START ) ; Read( handle, &header, sizeof( T_HEADER ) ) ; Close( handle ) ; return header.SizeFile ; } else { Close( handle ) ; return 0 ; } } /*══════════════════════════════════════════════════════════════════════════* █ █ █▀▀▀█ █▀▀▀█ █▄ ▄█ █▀▀▀█ █ █ █▀▀▀█ █▀▀▀▀ ██▀▀█ ██ ▄█ ██▀█▀ ██▀ █ ██▀▀█ ██ ██ ██ █ ██ ▀▀ ▀ ▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ *══════════════════════════════════════════════════════════════════════════*/ /*──────────────────────────────────────────────────────────────────────────*/ T_HQR_HEADER *HQR_Init_Ressource( char *hqrname, ULONG maxsize, UWORD maxindex ) { T_HQR_HEADER *header ; void *buffer ; if( !FileSize( hqrname ) ) return 0 ; // fichier ok ? header = Malloc( sizeof(T_HQR_HEADER) + sizeof(T_HQR_BLOC) * maxindex ) ; if( !header ) return 0 ; // mem ok ? buffer = Malloc( maxsize + RECOVER_AREA ) ; if( !buffer ) return 0 ; // mem ok ? strcpy( header->Name, hqrname ) ; header->MaxSize = header->FreeSize = maxsize ; header->MaxIndex = maxindex ; header->NbIndex = 0 ; header->Buffer = buffer ; return header ; // header } /*──────────────────────────────────────────────────────────────────────────*/ void HQR_Reset_Ressource( T_HQR_HEADER *header ) { header->FreeSize = header->MaxSize ; header->NbIndex = 0 ; } /*──────────────────────────────────────────────────────────────────────────*/ LONG HQR_Change_Ressource( T_HQR_HEADER *header, char *newhqrname ) { if( !FileSize( newhqrname ) ) return FALSE ; // fichier ok ? strcpy( header->Name, newhqrname ) ; header->FreeSize = header->MaxSize ; header->NbIndex = 0 ; return TRUE ; } /*──────────────────────────────────────────────────────────────────────────*/ void HQR_Free_Ressource( T_HQR_HEADER *header ) { if( header ) { Free( header->Buffer ) ; Free( header ) ; } } /*──────────────────────────────────────────────────────────────────────────*/ UWORD HQR_Del_Bloc( T_HQR_HEADER *header, WORD index ) { UWORD n ; T_HQR_BLOC *ptrbloc ; ULONG delsize ; UBYTE *ptr, *ptrs, *ptrd ; ptr = (UBYTE*)(header) + sizeof(T_HQR_HEADER) ; ptrbloc = (T_HQR_BLOC*)(ptr) ; delsize = ptrbloc[index].Size ; if( index < (header->NbIndex-1) ) { // shift buffer ptrd = header->Buffer + ptrbloc[index].Offset ; ptrs = ptrd + delsize ; memmove(ptrd, ptrs, ((header->Buffer+header->MaxSize) - ptrs) ) ; // shift index table ptrd = (UBYTE*)&ptrbloc[index] ; ptrs = ptrd + sizeof( T_HQR_BLOC ) ; memmove(ptrd, ptrs, (header->MaxIndex - (index + 1))*sizeof(T_HQR_BLOC) ) ; // shift index value for(n=index; n<(header->NbIndex-1); n++ ) { ptrbloc[n].Offset -= delsize ; } } header->NbIndex-- ; header->FreeSize += delsize ; return delsize ; } /*──────────────────────────────────────────────────────────────────────────*/ void *HQR_Get( T_HQR_HEADER *header, WORD index ) { UWORD n, oldest ; ULONG time, testtime ; UBYTE *ptr ; T_HQR_BLOC *ptrbloc ; ULONG size ; ULONG offset ; // ressources ULONG handle ; UWORD nbbloc ; ULONG buffer ; ULONG seekindex ; UBYTE *ptrdecomp ; T_HEADER lzssheader ; if( index < 0 ) return 0 ; if( (ptrbloc = HQR_GiveIndex( index, header->NbIndex, (UBYTE*)header+sizeof(T_HQR_HEADER) )) != 0 ) { // existing index ptrbloc->Time = TimerRef ; HQR_Flag = FALSE ; // marque non chargement ressource return( header->Buffer + ptrbloc->Offset ) ; } else // need load { // SaveTimer() ; size = Size_HQR( header->Name, index ) ; // load and expand hqr bloc handle = OpenRead( header->Name ) ; if( !handle ) return 0 ; Read( handle, &buffer, 4 ) ; nbbloc = (UWORD)(buffer / 4) ; if( index >= nbbloc ) { Close( handle ) ; return 0 ; } Seek( handle, index * 4, SEEK_START ) ; Read( handle, &seekindex, 4 ) ; if( !seekindex ) { Close( handle ) ; return 0 ; } Seek( handle, seekindex, SEEK_START ) ; Read( handle, &lzssheader, sizeof( T_HEADER ) ) ; // taille decompacte size = lzssheader.SizeFile ; if( !size ) { Close( handle ) ; return 0 ; } // gestion mémoire time = TimerRef ; ptr = (UBYTE*)(header) + sizeof(T_HQR_HEADER) ; ptrbloc = (T_HQR_BLOC*)(ptr) ; // check if enough space for bloc or index while( (size > header->FreeSize) OR (header->NbIndex >= header->MaxIndex) ) { // delete oldest bloc oldest = 0 ; testtime = 0 ; for( n=0; nNbIndex; n++ ) { if( (time-ptrbloc[n].Time) > testtime ) { testtime = time - ptrbloc[oldest].Time ; oldest = n ; } } HQR_Del_Bloc( header, oldest ) ; } // space size ok, load it ptr = header->Buffer + header->MaxSize - header->FreeSize ; // Load_HQR( header->Name, ptr, index ) ; switch( lzssheader.CompressMethod ) { case 0: /* Stored */ Read( handle, ptr, lzssheader.SizeFile ) ; break ; case 1: /* LZS */ ptrdecomp = (UBYTE*)ptr + lzssheader.SizeFile - lzssheader.CompressedSizeFile + RECOVER_AREA ; Read( handle, ptrdecomp, lzssheader.CompressedSizeFile ) ; Expand( ptrdecomp, ptr, lzssheader.SizeFile ) ; break ; default: Close( handle ) ; return 0 ; /* UnKnown version */ } Close( handle ) ; HQR_Flag = TRUE ; // indicate loaded ptrbloc[header->NbIndex].Index = index ; ptrbloc[header->NbIndex].Time = TimerRef ; ptrbloc[header->NbIndex].Offset = header->MaxSize - header->FreeSize ; ptrbloc[header->NbIndex].Size = size ; header->NbIndex++ ; header->FreeSize -= size ; // RestoreTimer() ; return ptr ; } } /*──────────────────────────────────────────────────────────────────────────*/ UWORD HQR_Del_Bloc_Sample( T_HQR_HEADER *header, WORD index ) { UWORD n ; T_HQR_BLOC *ptrbloc ; ULONG delsize ; UBYTE *ptr, *ptrs, *ptrd ; ptr = (UBYTE*)(header) + sizeof(T_HQR_HEADER) ; ptrbloc = (T_HQR_BLOC*)(ptr) ; delsize = ptrbloc[index].Size ; if( index < (header->NbIndex-1) ) { // shift buffer ptrd = header->Buffer + ptrbloc[index].Offset ; ptrs = ptrd + delsize ; /* memmove(ptrd, ptrs, ((header->Buffer+header->MaxSize) - ptrs) ) ; */ WaveMove(ptrd, ptrs, ((header->Buffer+header->MaxSize) - ptrs) ) ; // shift index table ptrd = (UBYTE*)&ptrbloc[index] ; ptrs = ptrd + sizeof( T_HQR_BLOC ) ; memmove(ptrd, ptrs, (header->MaxIndex - (index + 1))*sizeof(T_HQR_BLOC) ) ; // shift index value for(n=index; n<(header->NbIndex-1); n++ ) { ptrbloc[n].Offset -= delsize ; } } header->NbIndex-- ; header->FreeSize += delsize ; return delsize ; } /*──────────────────────────────────────────────────────────────────────────*/ void *HQR_GetSample( T_HQR_HEADER *header, WORD index ) { UWORD n, oldest ; ULONG time, testtime ; UBYTE *ptr ; T_HQR_BLOC *ptrbloc ; ULONG size ; ULONG offset ; // ressources ULONG handle ; UWORD nbbloc ; ULONG buffer ; ULONG seekindex ; UBYTE *ptrdecomp ; T_HEADER lzssheader ; if( index < 0 ) return 0 ; if( (ptrbloc = HQR_GiveIndex( index, header->NbIndex, (UBYTE*)header+sizeof(T_HQR_HEADER) )) != 0 ) { // existing index ptrbloc->Time = TimerRef ; HQR_Flag = FALSE ; // marque non chargement ressource return( header->Buffer + ptrbloc->Offset ) ; } else // need load { // SaveTimer() ; size = Size_HQR( header->Name, index ) ; // load and expand hqr bloc handle = OpenRead( header->Name ) ; if( !handle ) return 0 ; Read( handle, &buffer, 4 ) ; nbbloc = (UWORD)(buffer / 4) ; if( index >= nbbloc ) { Close( handle ) ; return 0 ; } Seek( handle, index * 4, SEEK_START ) ; Read( handle, &seekindex, 4 ) ; if( !seekindex ) { Close( handle ) ; return 0 ; } Seek( handle, seekindex, SEEK_START ) ; Read( handle, &lzssheader, sizeof( T_HEADER ) ) ; // taille decompacte size = lzssheader.SizeFile ; if( !size ) { Close( handle ) ; return 0 ; } // gestion mémoire time = TimerRef ; ptr = (UBYTE*)(header) + sizeof(T_HQR_HEADER) ; ptrbloc = (T_HQR_BLOC*)(ptr) ; // check if enough space for bloc or index while( (size > header->FreeSize) OR (header->NbIndex >= header->MaxIndex) ) { // delete oldest bloc oldest = 0 ; testtime = 0 ; for( n=0; nNbIndex; n++ ) { if( (time-ptrbloc[n].Time) > testtime ) { testtime = time - ptrbloc[oldest].Time ; oldest = n ; } } // méthode violente (attendre réflexions désagréables...) WaveStopOne( ptrbloc[oldest].Index ) ; HQR_Del_Bloc_Sample( header, oldest ) ; } // space size ok, load it ptr = header->Buffer + header->MaxSize - header->FreeSize ; // Load_HQR( header->Name, ptr, index ) ; switch( lzssheader.CompressMethod ) { case 0: /* Stored */ Read( handle, ptr, lzssheader.SizeFile ) ; break ; case 1: /* LZS */ ptrdecomp = (UBYTE*)ptr + lzssheader.SizeFile - lzssheader.CompressedSizeFile + RECOVER_AREA ; Read( handle, ptrdecomp, lzssheader.CompressedSizeFile ) ; Expand( ptrdecomp, ptr, lzssheader.SizeFile ) ; break ; default: Close( handle ) ; return 0 ; /* UnKnown version */ } Close( handle ) ; HQR_Flag = TRUE ; // indicate loaded ptrbloc[header->NbIndex].Index = index ; ptrbloc[header->NbIndex].Time = TimerRef ; ptrbloc[header->NbIndex].Offset = header->MaxSize - header->FreeSize ; ptrbloc[header->NbIndex].Size = size ; header->NbIndex++ ; header->FreeSize -= size ; // RestoreTimer() ; return ptr ; } }