diff --git a/Compiling instructions.txt b/Compiling instructions.txt index 2249e30..64db955 100644 --- a/Compiling instructions.txt +++ b/Compiling instructions.txt @@ -1,4 +1,4 @@ -All you need installed to compile Niotso for Windows, Linux, or Mac is GCC 4.6 or newer. +All you need installed to compile Niotso for Windows, Linux, or Mac is GCC 4.6 or newer, and NASM for libjpeg-turbo. Run "make" in this directory to compile every package. -j # will greatly speed up the compile time for processors with # cores. Run "make install" after compiling to install Niotso to your game directory; please specify it first in the Makefile. diff --git a/Libraries/FileHandler/utk/Makefile b/Libraries/FileHandler/utk/Makefile new file mode 100644 index 0000000..fcbba94 --- /dev/null +++ b/Libraries/FileHandler/utk/Makefile @@ -0,0 +1,30 @@ +# macros -------------------------------------------------------------------- +CC = gcc +LD = gcc +CFLAGS = -m32 -Wall -Wextra -Wabi -Os -march=i686 -fomit-frame-pointer -g0 +LDFLAGS = -m32 -s -fwhole-program + +AR = ar rcs +WINDRES = windres -F pe-i386 + +OBJECTS = obj/read_utk.o obj/utkdecode.o + +# These will rebuild the entire library upon edit. +DEPS = Makefile \ + read_utk.h + +# dependencies -------------------------------------------------------------- +all: utkdecode.exe + +$(OBJECTS): $(DEPS) + +utkdecode.exe: $(OBJECTS) + $(CC) $(LDFLAGS) -o $@ $(OBJECTS) + +# make rules ---------------------------------------------------------------- +obj/%.o: %.c + $(CC) -c -ansi -pedantic $(CFLAGS) -o $@ $< + +# maintenance --------------------------------------------------------------- +clean: + del /Q /S obj utkdecode.exe \ No newline at end of file diff --git a/Libraries/FileHandler/utk/read_utk.c b/Libraries/FileHandler/utk/read_utk.c new file mode 100644 index 0000000..b3ed1f7 --- /dev/null +++ b/Libraries/FileHandler/utk/read_utk.c @@ -0,0 +1,325 @@ +/* + read_utk.c - Copyright (c) 2011 Fatbag + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include +#include +#include +#include +#include "read_utk.h" + +#ifndef read_int32 + #define read_uint32(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3))) + #define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1))) +#endif + +#ifndef round + #define round(x) ((x) >= 0 ? (x)+0.5 : (x)-0.5) +#endif + +#ifndef __inline +#define __inline +#endif +#ifndef __restrict +#define __restrict +#endif + +float UTKTable1[64]; +uint8_t UTKTable2[512]; +const uint8_t UTKTable3[29] = {8,7,8,7,2,2,2,3,3,4,4,3,3,5,5,4,4,6,6,5,5,7,7,6,6,8,8,7,7}; +float UTKTable4[29]; + +int utk_read_header(utkheader_t * UTKHeader, const uint8_t * Buffer, unsigned FileSize) +{ + if(FileSize < 28) return 0; + memcpy(&UTKHeader->sID, Buffer, 4); + UTKHeader->dwOutSize = read_uint32(Buffer+4); + UTKHeader->dwWfxSize = read_uint32(Buffer+8); + UTKHeader->wFormatTag = read_uint16(Buffer+12); + UTKHeader->nChannels = read_uint16(Buffer+14); + UTKHeader->nSamplesPerSec = read_uint32(Buffer+16); + UTKHeader->nAvgBytesPerSec = read_uint32(Buffer+20); + UTKHeader->nBlockAlign = read_uint16(Buffer+24); + UTKHeader->wBitsPerSample = read_uint16(Buffer+26); + UTKHeader->cbSize = read_uint32(Buffer+28); + + if(memcmp(UTKHeader->sID, "UTM0", 4) || + UTKHeader->wFormatTag != 1 || + UTKHeader->nChannels != 1 || + UTKHeader->nSamplesPerSec < 8000 || UTKHeader->nSamplesPerSec > 192000 || + !(UTKHeader->nSamplesPerSec%8000==0 || UTKHeader->nSamplesPerSec%11025==0) || + UTKHeader->wBitsPerSample != 16 || + UTKHeader->nBlockAlign != UTKHeader->nChannels*(UTKHeader->wBitsPerSample>>3) || + UTKHeader->nAvgBytesPerSec != UTKHeader->nSamplesPerSec*UTKHeader->nBlockAlign || + UTKHeader->dwOutSize%UTKHeader->nBlockAlign != 0 || + UTKHeader->cbSize != 0 + ) return 0; + + UTKHeader->Frames = UTKHeader->dwOutSize/UTKHeader->nBlockAlign; + UTKHeader->UTKDataSize = FileSize - 32; + + return 1; +} + +int utk_decode(const uint8_t *__restrict InBuffer, uint8_t *__restrict OutBuffer, unsigned Frames){ + utkparams_t p; + p.InData = InBuffer; + SetUTKParameters(&p); + + while(Frames){ + int i, BlockSize = (Frames > 432) ? 432 : Frames; + DecompressBlock(&p); + + for(i=0; i 32768) + value = 98304; + + *(OutBuffer++) = (value&0x00FFu)>>(8*0); + *(OutBuffer++) = (value&0xFF00u)>>(8*1); + } + Frames -= BlockSize; + } + return 1; +} + +void UTKGenerateTables(void){ + /* Call once */ + int i; + + /* UTKTable1 */ + UTKTable1[0] = 0; + for(i=-31; i<32; i++){ + int s = (i>=0) ? 1 : -1; + if (s*i<14) UTKTable1[i+32] = i*.051587f; + else if(s*i<25) UTKTable1[i+32] = i*.051587f/2 + s*.337503f; + else UTKTable1[i+32] = i*.051587f/8 + s*.796876f; + } + + /* UTKTable2 */ + for(i=0; i<512; i++){ + switch(i%4){ + case 0: UTKTable2[i] = 4; break; + case 1: UTKTable2[i] = (i<256) ? 6 : (11 + (i%8 > 4)); break; + case 2: UTKTable2[i] = (i<256) ? 5 : (7 + (i%8 > 4)); break; + case 3: { + uint8_t l1[] = {9,15,13,19,10,16}; + uint8_t l2[] = {17,21,18,25,17,22,18,00,17,21,18,26,17,22,18,02, + 23,27,24,01,23,28,24,03,23,27,24,01,23,28,24,03}; + if(i%16 < 4) UTKTable2[i] = l1[0 + (i>256)]; + else if(i%16 < 8) UTKTable2[i] = l1[2 + (i>256)] + (i%32 > 16); + else if(i%16 < 12) UTKTable2[i] = l1[4 + (i>256)]; + else UTKTable2[i] = l2[i/16]; + } break; + } + } + + /* UTKTable4 */ + UTKTable4[0] = 0; + for(i=0; i<7; i++){ + UTKTable4[4*i+1] = -i; + UTKTable4[4*i+2] = +i; + UTKTable4[4*i+3] = -i; + UTKTable4[4*i+4] = +i; + } +} + +uint8_t ReadBits(utkparams_t *p, uint8_t i){ + unsigned returnvalue = (255>>(8-i)) & p->x; + p->x >>= i; + p->y -= i; + + if(p->y < 8){ + unsigned value = *(p->InData++); + p->x |= value << (p->y&0xFF); + p->y += 8; + } + return returnvalue; +} + +void SetUTKParameters(utkparams_t *p){ + int i; + float s; + p->x = *(p->InData++); + p->y = 8; + p->a = ReadBits(p, 1); + p->b = 32 - ReadBits(p, 4); + p->c[0] = (ReadBits(p, 4)+1)*8; + + s = ((float)ReadBits(p, 6))/1000 + 1.04; + for(i=1; i<64; i++) + p->c[i] = p->c[i-1]*s; + + memset(&p->c[64], 0, 24*sizeof(float)); + memset(p->d, 0, 324*sizeof(float)); +} + +void DecompressBlock(utkparams_t *p){ + int i,j; + float Window[118]; + float Matrix[12]; + int Branch = 0; + + memset(&Window[0], 0, 5*sizeof(float)); + memset(&Window[113], 0, 5*sizeof(float)); + + for(i=0; i<12; i++){ + unsigned result = ReadBits(p, (i<4) ? 6 : 5); + if(i==0 && p->b > result) Branch++; + Matrix[i] = (UTKTable1[result + ((i<4)?0:16)] - p->c[64+i])/4; + } + + for(i=0; i<4; i++){ + float c1, c2; + int o = (int)ReadBits(p, 8); + c1 = ((float)ReadBits(p, 4))/15; + c2 = p->c[ReadBits(p, 6)]; + + if(!p->a){ + Unknown1(p, Branch, &Window[5], 1); + }else{ + unsigned x = ReadBits(p, 1); + unsigned y = ReadBits(p, 1); + Unknown1(p, Branch, &Window[5+x], 2); + + if(y){ + for(j=0; j<108; j+=2) + Window[6-x + j] = 0; + }else{ + float *z = &Window[6-x]; + for(j=0; j<54; j++, z+=2) + *z = + (z[-5]+z[+5]) * .0180326793f + - (z[-3]+z[+3]) * .1145915613f + + (z[-1]+z[+1]) * .5973859429f; + + c2 /= 2; + } + } + + for(j=0; j<108; j++) + p->DecompressedBlock[108*i + j] = c2*Window[5+j] + c1*p->d[216 + 108*i + j - o]; + } + + memcpy(p->d, &p->DecompressedBlock[108], 324*sizeof(DWORD)); + + for(i=0; i<4; i++){ + for(j=0; j<12; j++) + p->c[64+j] += Matrix[j]; + + Unknown2(p, i*12, (i!=3) ? 1 : 33); + } +} + +void Unknown1(utkparams_t *p, int Branch, float * Window, int Interval){ + if(Branch != 0){ + unsigned a = 0; + unsigned i = 0; + while(i<108){ + unsigned value = UTKTable2[(a<<8) | (p->x&0xFF)]; + a = (value<2 || value>8); + ReadBits(p, UTKTable3[value]); + + if(value >= 4){ + Window[i] = UTKTable4[value]; + i += Interval; + }else{ + if(value > 1){ + unsigned x = ReadBits(p, 6)+7; + if(x > (108 - i)/Interval) + x = (108 - i)/Interval; + + while(x--){ + Window[i] = 0; + i += Interval; + } + }else{ + Window[i] = 7; + while(ReadBits(p, 1)) + Window[i]++; + + if(!ReadBits(p, 1)) + Window[i] *= -1; + + i += Interval; + } + } + } + }else{ + int i; + for(i=0; i<108; i+=Interval){ + uint8_t b; + switch(p->x & 3){ + case 3: + Window[i] = 2.0; + b = 2; + break; + case 1: + Window[i] = -2.0; + b = 2; + break; + default: + Window[i] = 0.0; + b = 1; + } + + ReadBits(p, b); + } + } +} + +void Unknown2(utkparams_t *p, unsigned Sample, unsigned Blocks){ + unsigned i,j; + float Matrix[12]; + int offset = 75; + Unknown2_1(&p->c[64], Matrix); + + for(i=0; iDecompressedBlock[Sample]; + for(j=0; j<12; j++){ + if(++offset == 88) offset = 76; + x += p->c[offset] * Matrix[j]; + } + p->c[offset--] = x; + p->DecompressedBlock[Sample++] = x; + } +} + +void Unknown2_1(float *__restrict c64, float *__restrict Matrix){ + int i,j; + float LocalMatrix1[12]; + float LocalMatrix2[12]; + LocalMatrix2[0] = 1; + memcpy(&LocalMatrix2[1], c64, 11*sizeof(float)); + + for(i=0; i<12; i++){ + float x = 0; + for(j=11; j>=0; j--){ + x -= c64[j] * LocalMatrix2[j]; + if(j != 11) + LocalMatrix2[j+1] = x*c64[j] + LocalMatrix2[j]; + } + LocalMatrix2[0] = x; + LocalMatrix1[i] = x; + + for(j=0; j + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +typedef struct +{ + char sID[4]; + DWORD dwOutSize; + DWORD dwWfxSize; + /* WAVEFORMATEX */ + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + WORD wBitsPerSample; + DWORD cbSize; + + unsigned Frames; + unsigned UTKDataSize; +} utkheader_t; + +typedef struct { + const uint8_t *InData; + unsigned x, y; + unsigned a, b; + float c[88]; + float d[324]; + float DecompressedBlock[432]; +} utkparams_t; + +#ifdef __cplusplus +extern "C" { +#endif + +int utk_read_header(utkheader_t * UTKHeader, const uint8_t * Buffer, unsigned FileSize); +int utk_decode(const uint8_t *__restrict InBuffer, uint8_t *__restrict OutBuffer, unsigned Frames); +void UTKGenerateTables(void); +uint8_t ReadCC(utkparams_t *p, uint8_t i); +void SetUTKParameters(utkparams_t *p); +void DecompressBlock(utkparams_t *p); +void Unknown1(utkparams_t *p, int Branch, float * Window, int Interval); +void Unknown2(utkparams_t *p, unsigned Sample, unsigned Blocks); +void Unknown2_1(float *__restrict c64, float *__restrict Matrix); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Libraries/FileHandler/utk/utkdecode.c b/Libraries/FileHandler/utk/utkdecode.c new file mode 100644 index 0000000..fb380e9 --- /dev/null +++ b/Libraries/FileHandler/utk/utkdecode.c @@ -0,0 +1,164 @@ +/* + utkdecode.c - Copyright (c) 2011 Fatbag + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include +#include +#include +#include "read_utk.h" + +#ifndef write_int32 + #define write_uint32(dest, src) \ + (dest)[0] = ((src)&0x000000FF)>>(8*0); \ + (dest)[1] = ((src)&0x0000FF00)>>(8*1); \ + (dest)[2] = ((src)&0x00FF0000)>>(8*2); \ + (dest)[3] = ((src)&0xFF000000)>>(8*3) + #define write_uint16(dest, src) \ + (dest)[0] = ((src)&0x00FF)>>(8*0); \ + (dest)[1] = ((src)&0xFF00)>>(8*1) +#endif + +int main(int argc, char *argv[]){ + int overwrite = 0; + char *InFile, *OutFile; + HANDLE hFile; + HANDLE ProcessHeap = GetProcessHeap(); + unsigned FileSize; + DWORD bytestransferred = 0; + uint8_t * UTKData; + utkheader_t UTKHeader; + + if(argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){ + printf("Usage: utkdecode [-f] infile outfile\n" + " -or- utkdecode infile\n" + "Transcode or play a Maxis UTalk sound.\n" + "Use -f to force overwriting without confirmation.\n" + "\n" + "Report bugs to .\n" + "utkdecode is maintained by the Niotso project.\n" + "Home page: "); + return 0; + } + + if(argc >= 4 && !strcmp(argv[1], "-f")){ + overwrite++; + InFile = argv[2]; + OutFile = argv[3]; + }else{ + InFile = argv[1]; + OutFile = argv[2]; + } + + /**** + ** Open the file and read in entire contents to memory + */ + + hFile = CreateFile(InFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if(hFile == INVALID_HANDLE_VALUE){ + if(GetLastError() == ERROR_FILE_NOT_FOUND){ + printf("%sThe specified input file does not exist.", "utkdecode: error: "); + return -1; + } + printf("%sThe input file could not be opened for reading.", "utkdecode: error: "); + return -1; + } + FileSize = GetFileSize(hFile, NULL); + if(FileSize < 24){ + printf("%sNot a valid UTK file.", "utkdecode: error: "); + return -1; + } + UTKData = HeapAlloc(ProcessHeap, HEAP_NO_SERIALIZE, FileSize); + if(UTKData == NULL){ + printf("%sMemory for this file could not be allocated.", "utkdecode: error: "); + return -1; + } + if(!ReadFile(hFile, UTKData, FileSize, &bytestransferred, NULL) || bytestransferred != FileSize){ + printf("%sThe input file could not be read.", "utkdecode: error: "); + return -1; + } + CloseHandle(hFile); + + /**** + ** Transcode the data from UTK to LPCM + */ + + if(!utk_read_header(&UTKHeader, UTKData, FileSize)){ + printf("%sNot a valid UTK file.", "utkdecode: error: "); + return -1; + } + + if(argc >= 3){ /* Transcode */ + uint8_t * WaveData = HeapAlloc(ProcessHeap, HEAP_NO_SERIALIZE, 44+UTKHeader.dwOutSize); + if(WaveData == NULL){ + printf("%sMemory for this file could not be allocated.", "utkdecode: error: "); + return -1; + } + + UTKGenerateTables(); + + if(!utk_decode(UTKData+32, WaveData+44, UTKHeader.Frames)){ + printf("%sMemory for this file could not be allocated.", "utkdecode: error: "); + return -1; + } + + HeapFree(ProcessHeap, HEAP_NO_SERIALIZE, UTKData); + + /**** + ** Write the Microsoft WAV header + */ + + write_uint32(WaveData, 0x46464952); /* "RIFF" */ + write_uint32(WaveData+4, 36+UTKHeader.dwOutSize); + write_uint32(WaveData+8, 0x45564157); /* "WAVE" */ + write_uint32(WaveData+12, 0x20746d66); /* "fmt " */ + write_uint32(WaveData+16, 16); + write_uint16(WaveData+20, 1); + write_uint16(WaveData+22, UTKHeader.nChannels); + write_uint32(WaveData+24, UTKHeader.nSamplesPerSec); + write_uint32(WaveData+28, UTKHeader.nAvgBytesPerSec); + write_uint16(WaveData+32, UTKHeader.nBlockAlign); + write_uint16(WaveData+34, UTKHeader.wBitsPerSample); + write_uint32(WaveData+36, 0x61746164); /* "data" */ + write_uint32(WaveData+40, UTKHeader.dwOutSize); + + /**** + ** Write the contents to the output file + */ + + hFile = CreateFile(OutFile, GENERIC_WRITE, 0, NULL, CREATE_NEW+overwrite, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if(hFile == INVALID_HANDLE_VALUE){ + if(!overwrite && GetLastError() == ERROR_FILE_EXISTS){ + char c; + printf("File \"%s\" exists.\nContinue anyway? (y/n) ", OutFile); + c = getchar(); + if(c != 'y' && c != 'Y'){ + printf("\nAborted."); + return -1; + } + hFile = CreateFile(OutFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + } + if(hFile == INVALID_HANDLE_VALUE){ + printf("%sThe output file could not be opened for writing.", "utkdecode: error: "); + return -1; + } + } + WriteFile(hFile, WaveData, 44+UTKHeader.dwOutSize, &bytestransferred, NULL); + CloseHandle(hFile); + } + + return 0; +} \ No newline at end of file diff --git a/Libraries/FileHandler/xa/read_xa.c b/Libraries/FileHandler/xa/read_xa.c index 629a186..cf60e97 100644 --- a/Libraries/FileHandler/xa/read_xa.c +++ b/Libraries/FileHandler/xa/read_xa.c @@ -37,12 +37,12 @@ unsigned xa_compressed_size(unsigned Frames, unsigned Channels) { - /* The required input size is: - ** Channels * (ceil(n/2) + ceil(n/28)) - ** | a | | b | + /* This function calculates the size of compressed XA data with known frames and channels, as such: + ** Channels * (ceil(Frames/2) + ceil(Frames/28)) + ** | a | | b | ** - ** a = The space required for all 2-sample bytes in the XA data for a single channel (Period: 2 frames) - ** b = The space required for all control bytes in the XA data for a single channel (Period: 28 frames) + ** a = The space required for all sample bytes in the XA data for a single channel (1 byte every 2 frames) + ** b = The space required for all control bytes in the XA data for a single channel (1 byte every 28 frames) ** (a+b) is multiplied by Channels to produce the final size ** ** This source package assumes a partial block at the end of the XA data is legal but a partial frame is not. diff --git a/Makefile b/Makefile index f743716..dccb08b 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,9 @@ buildenv = cmd # Installation directory (do not use backslashes) installdir = c:/Program Files (x86)/Maxis/The Sims Online/Niotso +# Debugging (valid options: yes no) +debug = no + # Profile-guided optimization (valid options: none instrument optimize) pgo = none @@ -21,6 +24,8 @@ LDFLAGS = -m32 -static -static-libgcc ARFLAGS = rcs RCFLAGS = -F pe-i386 +CFLAGS_LANG_C = +CFLAGS_LANG_CPP = #### ## [Profiles] @@ -46,13 +51,13 @@ WARNINGS = -Wall -Wextra -pedantic ifeq ($(buildenv),cmd) RM_R = -@del /s /q CP_F = copy /y - EXE = .exe - DLL = .dll + EXE = .exe + DLL = .dll else RM_R = -@rm -r CP_F = cp -f - EXE = - DLL = .so + EXE = + DLL = .so endif ifeq ($(pgo),instrument) @@ -68,11 +73,16 @@ endif include packages.makefile +filter_obj = *.o *.lo *.la *.Plo *.Pla *.gch *.pch *.obj *.res *.exp *.dep *.aps *.intermediate.manifest +filter_exe = *.exe *.dll *.so *.a *.lib +filter_profile = *.gcda +filter_dist = *.dsp *.dsw *.user *.ncb *.pdb *.idb *.opt *.plg *.suo */BuildLog.htm + objclean: - $(RM_R) *.o *.lo *.la *.Plo *.Pla *.gch *.pch *.obj *.res - + $(RM_R) $(filter_obj) clean: objclean - $(RM_R) *.exe *.dll *.so *.a *.lib - -distclean: clean - $(RM_R) *.gcda \ No newline at end of file + $(RM_R) $(filter_obj) $(filter_exe) +profileclean: + $(RM_R) $(filter_profile) +distclean: + $(RM_R) $(filter_obj) $(filter_exe) $(filter_profile) $(filter_dist) \ No newline at end of file