CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

ADPCM.CPP (2178B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 #include "function.h"
     17 
     18 extern "C" {
     19 #include "soscomp.h"
     20 #include "itable.cpp"
     21 #include "dtable.cpp"
     22 
     23 
     24 void sosCODECInitStream(_SOS_COMPRESS_INFO* info)
     25 {
     26 	info->dwSampleIndex = 0;
     27 	info->dwPredicted = 0;
     28 }
     29 
     30 
     31 unsigned long sosCODECDecompressData(_SOS_COMPRESS_INFO* info, unsigned long numbytes)
     32 {
     33 	unsigned long token;
     34 	long sample;
     35 	unsigned int fastindex;
     36 	unsigned char *inbuff;
     37 	unsigned short *outbuff;
     38 
     39 	inbuff = (unsigned char *)info->lpSource;
     40 	outbuff = (unsigned short *)info->lpDest;
     41 
     42 	// Preload variables before the big loop
     43 	fastindex = (unsigned int)info->dwSampleIndex;
     44 	sample = info->dwPredicted;
     45 
     46 	if (!numbytes)
     47 		goto SkipLoop;
     48 
     49 	do {
     50 		// First nibble
     51 		token = *inbuff++;
     52 		fastindex += token & 0x0f;
     53 		sample += DiffTable[fastindex];
     54 		fastindex = IndexTable[fastindex];
     55 		if (sample > 32767L)
     56 			sample = 32767L;
     57 		if (sample < -32768L)
     58 			sample = -32768L;
     59 		*outbuff++ = (unsigned short)sample;
     60 
     61 		// Second nibble
     62 		fastindex += token >> 4;
     63 		sample += DiffTable[fastindex];
     64 		fastindex = IndexTable[fastindex];
     65 		if (sample > 32767L)
     66 			sample = 32767L;
     67 		if (sample < -32768L)
     68 			sample = -32768L;
     69 		*outbuff++ = (unsigned short)sample;
     70 	} while(--numbytes);
     71 
     72 SkipLoop:
     73 
     74 	// Put local vars back
     75 	info->dwSampleIndex = (unsigned long)fastindex;
     76 	info->dwPredicted = sample;
     77 	return(numbytes << 2);
     78 }
     79 
     80 }