400 lines
7.8 KiB
C++
400 lines
7.8 KiB
C++
|
#include <windows.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <stdarg.h>
|
|||
|
#include <string.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <time.h>
|
|||
|
#include <math.h>
|
|||
|
#include <io.h>
|
|||
|
|
|||
|
//#include "SfxList.h"
|
|||
|
|
|||
|
|
|||
|
//************************************************
|
|||
|
|
|||
|
#define MAX_SFX 1024
|
|||
|
|
|||
|
//************************************************
|
|||
|
|
|||
|
char path_buffer[_MAX_PATH];
|
|||
|
char drive[_MAX_DRIVE];
|
|||
|
char dir[_MAX_DIR];
|
|||
|
char fname[_MAX_FNAME];
|
|||
|
char ext[_MAX_EXT];
|
|||
|
|
|||
|
|
|||
|
struct bank_entry
|
|||
|
{
|
|||
|
WORD looped;
|
|||
|
WORD pitch;
|
|||
|
DWORD offset;
|
|||
|
};
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
char Name[ 100 ];
|
|||
|
WORD SfxNo;
|
|||
|
BYTE Hashed;
|
|||
|
BYTE Looped;
|
|||
|
WORD LoopPos;
|
|||
|
} file_entry;
|
|||
|
|
|||
|
|
|||
|
char ThisDir[256];
|
|||
|
file_entry FileList[MAX_SFX];
|
|||
|
int NoFiles = 0;
|
|||
|
|
|||
|
|
|||
|
//***********************************************************************
|
|||
|
//***********************************************************************
|
|||
|
|
|||
|
static void app_debug_msg(const char * pszFmt,va_list args)
|
|||
|
{
|
|||
|
char szBuf[256];
|
|||
|
|
|||
|
vsprintf(szBuf,pszFmt,args);
|
|||
|
printf("\n%s\n",szBuf);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//******************************************************************
|
|||
|
//******************************************************************
|
|||
|
|
|||
|
void __cdecl screen_debug_msg(const char * pszFmt,...)
|
|||
|
{
|
|||
|
if (pszFmt)
|
|||
|
{
|
|||
|
va_list args;
|
|||
|
va_start(args,pszFmt);
|
|||
|
app_debug_msg(pszFmt,args);
|
|||
|
va_end(args);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void __cdecl app_assert(const char * pszFmt,...)
|
|||
|
{
|
|||
|
if (pszFmt)
|
|||
|
{
|
|||
|
va_list args;
|
|||
|
va_start(args,pszFmt);
|
|||
|
app_debug_msg(pszFmt,args);
|
|||
|
va_end(args);
|
|||
|
}
|
|||
|
exit(123);
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************
|
|||
|
|
|||
|
void FreePtr(void *p)
|
|||
|
{
|
|||
|
if(p) free(p);
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************
|
|||
|
|
|||
|
BYTE* LoadFileInMem(const char * pszName)
|
|||
|
{
|
|||
|
HANDLE hsFile;
|
|||
|
DWORD dwSize = NULL;
|
|||
|
DWORD dwSize2 = NULL;
|
|||
|
DWORD Temp;
|
|||
|
BYTE* Buffer;
|
|||
|
|
|||
|
if( (hsFile = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|||
|
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == INVALID_HANDLE_VALUE )
|
|||
|
{
|
|||
|
screen_debug_msg("LFIM: Could not open file %s",pszName);
|
|||
|
return NULL;
|
|||
|
}else{
|
|||
|
dwSize = GetFileSize(hsFile,NULL);
|
|||
|
dwSize2 = dwSize;
|
|||
|
if(dwSize&0x7) dwSize2 = (dwSize-(dwSize&0x7))+8;
|
|||
|
if( (Buffer=(BYTE*)malloc(dwSize2))==NULL ) {printf("Out of memory.\n");exit(123);}
|
|||
|
ReadFile(hsFile,(void*)Buffer,dwSize,&Temp,NULL);
|
|||
|
CloseHandle(hsFile);
|
|||
|
}
|
|||
|
|
|||
|
return Buffer;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//******************************************************************
|
|||
|
|
|||
|
DWORD FindFileSize(const char * pszName)
|
|||
|
{
|
|||
|
HANDLE hsFile;
|
|||
|
DWORD dwSize=NULL;
|
|||
|
|
|||
|
if( (hsFile = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|||
|
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == INVALID_HANDLE_VALUE )
|
|||
|
{
|
|||
|
screen_debug_msg("\nFFS: Could not open file %s",pszName);
|
|||
|
return NULL;
|
|||
|
}else{
|
|||
|
dwSize = GetFileSize(hsFile,NULL);
|
|||
|
if(dwSize&0x7) dwSize = (dwSize-(dwSize&0x7))+8;
|
|||
|
CloseHandle(hsFile);
|
|||
|
}
|
|||
|
|
|||
|
return dwSize;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//***************************************************
|
|||
|
// Find files in directory
|
|||
|
//***************************************************
|
|||
|
|
|||
|
int CalcHashNum(char* astring)
|
|||
|
{
|
|||
|
int result = 0;
|
|||
|
WORD count;
|
|||
|
|
|||
|
for (count=0; count<strlen(astring); count++)
|
|||
|
{
|
|||
|
result^=(int) astring[count];
|
|||
|
result++;
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void FindDirFiles(char * Search)
|
|||
|
{
|
|||
|
int i;
|
|||
|
FILE *fh;
|
|||
|
char loop;
|
|||
|
|
|||
|
|
|||
|
/* De-hash table */
|
|||
|
for(i=0;i<MAX_SFX;i++)
|
|||
|
{
|
|||
|
FileList[i].Name[ 0 ] = '\0';
|
|||
|
FileList[i].Hashed = false;
|
|||
|
FileList[i].Looped = false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Open source file
|
|||
|
if( ( fh = fopen( Search, "rb" ) ) == NULL )
|
|||
|
{
|
|||
|
printf( "\nCan't find source file!\n" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Scan source file
|
|||
|
while( !feof( fh ) )
|
|||
|
{
|
|||
|
if( fscanf( fh, "%s %c %d", FileList[NoFiles].Name, &loop, &FileList[NoFiles].LoopPos ) != 3 )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
if( loop == 'y' || loop == 'Y' )
|
|||
|
{
|
|||
|
FileList[NoFiles].Looped = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
FileList[NoFiles].Looped = false;
|
|||
|
}
|
|||
|
FileList[NoFiles].Hashed = true;
|
|||
|
NoFiles++;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//***************************************************
|
|||
|
// Write files to bank
|
|||
|
//***************************************************
|
|||
|
|
|||
|
DWORD FlipLongWord(DWORD val)
|
|||
|
{
|
|||
|
DWORD result;
|
|||
|
|
|||
|
result = ((val&0x000000ff)<<24) + ((val&0x0000ff00)<<8) + ((val&0x00ff0000)>>8) + ((val&0xff000000)>>24);
|
|||
|
|
|||
|
return(result);
|
|||
|
}
|
|||
|
|
|||
|
void WriteBankData(char* Bank)
|
|||
|
{
|
|||
|
FILE* BANKFILE = NULL;
|
|||
|
FILE* OFFSETFILE = NULL;
|
|||
|
BYTE* Buffer = NULL;
|
|||
|
WORD Size;
|
|||
|
DWORD filepos = 0;
|
|||
|
char file[256];
|
|||
|
bank_entry BankInfo;
|
|||
|
WORD pitch;
|
|||
|
DWORD vagpitch;
|
|||
|
|
|||
|
sprintf(file,"%s.bnk",Bank);
|
|||
|
BANKFILE = fopen(file,"wb");
|
|||
|
if(!BANKFILE) {printf("\nBank file error\n\n");return;}
|
|||
|
|
|||
|
sprintf(file,"%s.bof",Bank);
|
|||
|
OFFSETFILE = fopen(file,"wb");
|
|||
|
if(!OFFSETFILE) {printf("\nBank offset error\n\n");return;}
|
|||
|
|
|||
|
for(int i=0;i<NoFiles;i++)
|
|||
|
{
|
|||
|
if(FileList[i].Hashed)
|
|||
|
{
|
|||
|
char Name[256];
|
|||
|
sprintf(Name, "%s%s", ThisDir, FileList[i].Name);
|
|||
|
Buffer = LoadFileInMem(Name);
|
|||
|
if (Buffer)
|
|||
|
{
|
|||
|
Size = (WORD)FindFileSize(Name);
|
|||
|
Size -= 48;
|
|||
|
|
|||
|
printf("%s\t\t", Name);
|
|||
|
|
|||
|
if( FileList[i].Looped )
|
|||
|
{
|
|||
|
// Encode vag file as looped
|
|||
|
int LoopBlock = (int)( (float)FileList[i].LoopPos / 3.5f );
|
|||
|
for(int p=48+16;p<(LoopBlock)-16;p+=16)
|
|||
|
{
|
|||
|
Buffer[p+1] = 0x0;
|
|||
|
}
|
|||
|
|
|||
|
Buffer[p+1] = 0x6;
|
|||
|
for(p=p+16;p<(Size-16);p+=16)
|
|||
|
{
|
|||
|
Buffer[p+1] = 0x2;
|
|||
|
}
|
|||
|
Buffer[p+1] = 0x3;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Encode vag file as non-looped
|
|||
|
for(int p=48;p<(Size-16);p+=16)
|
|||
|
{
|
|||
|
// Buffer[p+1] = 0x2;
|
|||
|
}
|
|||
|
Buffer[p+1] = 0x1;
|
|||
|
}
|
|||
|
|
|||
|
fwrite(Buffer+48, 1, Size, BANKFILE);
|
|||
|
|
|||
|
_splitpath(Name, drive, dir, fname, ext);
|
|||
|
|
|||
|
vagpitch = *(DWORD*)&Buffer[16];
|
|||
|
vagpitch = FlipLongWord(vagpitch);
|
|||
|
pitch=(int)((float)vagpitch*(1024.0/11025.0));
|
|||
|
printf(" pitch %dkhz (%d)\n",vagpitch,pitch);
|
|||
|
|
|||
|
BankInfo.offset = filepos;
|
|||
|
BankInfo.pitch = pitch;
|
|||
|
BankInfo.looped = FileList[i].Looped;
|
|||
|
|
|||
|
fwrite(&BankInfo, 1, sizeof(bank_entry), OFFSETFILE);
|
|||
|
|
|||
|
filepos += Size;
|
|||
|
|
|||
|
FreePtr(Buffer);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
fclose(BANKFILE);
|
|||
|
fclose(OFFSETFILE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static const char BadFileChars[] =
|
|||
|
{
|
|||
|
'+', '-', '*', '/', '\\', '#', ',',
|
|||
|
'.', '(', ')', '!', '"', '<EFBFBD>', '$',
|
|||
|
'%', '^', '&', '=', '#', ':', ';', '<',
|
|||
|
'>', '?', '@', '{', '}', '[', ']', '<EFBFBD>',
|
|||
|
};
|
|||
|
|
|||
|
static const int nbBadFileChars = (sizeof(BadFileChars) / sizeof(char));
|
|||
|
|
|||
|
|
|||
|
void ExportEnums(char * name)
|
|||
|
{
|
|||
|
FILE * ENUMFILE = NULL;
|
|||
|
char file[256];
|
|||
|
|
|||
|
_splitpath(name, drive, dir, fname, ext);
|
|||
|
strupr(fname);
|
|||
|
sprintf( file, "%s.h", name );
|
|||
|
ENUMFILE = fopen(file,"wt");
|
|||
|
if(!ENUMFILE) {printf("\nEnum file error\n\n");return;}
|
|||
|
|
|||
|
fprintf( ENUMFILE, "enum\n{\n" );
|
|||
|
for (int i=0;i<NoFiles;i++)
|
|||
|
{
|
|||
|
char * ostr = FileList[i].Name;//SFXNameTab[i];
|
|||
|
int len = (int)strlen(ostr)+1;
|
|||
|
char * nstr = new char[len];
|
|||
|
|
|||
|
for (int t=len-1;t>=0;t--)
|
|||
|
{
|
|||
|
if( ostr[ t ] == '\\' )
|
|||
|
{
|
|||
|
t++;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int o = 0;
|
|||
|
for (;t<len;t++)
|
|||
|
{
|
|||
|
nstr[o] = ostr[t];
|
|||
|
if (nstr[o] == '.') nstr[o] = 0;
|
|||
|
for(int c=0;c<nbBadFileChars;c++)
|
|||
|
{
|
|||
|
if (nstr[o] == BadFileChars[c]) nstr[o] = '_';
|
|||
|
}
|
|||
|
o++;
|
|||
|
}
|
|||
|
|
|||
|
strupr( nstr );
|
|||
|
|
|||
|
if( FileList[i].Looped )
|
|||
|
{
|
|||
|
fprintf( ENUMFILE, "\tSFX_%s_%s,\t\t// Looped at %d\n", fname,nstr, FileList[i].LoopPos );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
fprintf( ENUMFILE, "\tSFX_%s_%s,\n", fname,nstr );
|
|||
|
}
|
|||
|
}
|
|||
|
fprintf( ENUMFILE, "};\n" );
|
|||
|
}
|
|||
|
|
|||
|
//***************************************************
|
|||
|
//***************************************************
|
|||
|
//***************************************************
|
|||
|
//***************************************************
|
|||
|
|
|||
|
int main(int argc, char *argv[])
|
|||
|
{
|
|||
|
|
|||
|
if(argc!=3)
|
|||
|
{
|
|||
|
printf("\nBanker (C)limax 1997");
|
|||
|
printf("\nWritten by Tim Swann");
|
|||
|
printf("\nUsage: Banker <Source File> <Output Base>");
|
|||
|
printf("\nFor example, 'Banker level0.txt \\data\\snd\\level0' will take");
|
|||
|
printf("\n'level0.txt' as its input and produce three files ( \\data\\snd\\level0.bof,");
|
|||
|
printf("\n\\data\\snd\\level0.bnk and \\data\\snd\\level0.h ) as output.");
|
|||
|
printf("\n\n");
|
|||
|
return(0);
|
|||
|
}
|
|||
|
|
|||
|
FindDirFiles(argv[1]);
|
|||
|
WriteBankData(argv[2]);
|
|||
|
ExportEnums(argv[2]);
|
|||
|
|
|||
|
printf("\nBank files made\n\n");
|
|||
|
|
|||
|
return(0);
|
|||
|
}
|