SBSPSS/Utils/MkSpeech/MkSpeech.cpp
2001-05-05 21:18:12 +00:00

415 lines
9.4 KiB
C++
Raw Permalink Blame History

/***********************/
/*** Speech Compiler ***/
/***********************/
#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 <fstream.h>
#include <conio.h>
#include <vector>
using namespace std;
//************************************************
#define CHUNKSIZE 2336 // XA track size
#define SPACE ' '
#define MINUS '-'
#define COMMENT '#'
#define TAB 0x09
#define EOL 0x0d
#define InFileEXT "Ixa"
#define OutFileEXT "XaB"
#define BANK_SHIFT 16
//************************************************
struct sLang
{
char *Dir;
char Prefix;
};
struct sInFile
{
char Name[256];
int Chunks;
int Offset;
};
//************************************************
char *Script;
char *OutDir="",*ScriptFile=0;
int IncFileSet=0;
char IncludeFilename[256];
int BankNo=0;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
std::vector<sLang> LangList;
std::vector<sInFile> FileList;
//***********************************************************************
//***********************************************************************
static void app_debug_msg(const char * pszFmt,va_list args)
{
char szBuf[256];
vsprintf(szBuf,pszFmt,args);
printf("%s\n",szBuf);
}
//******************************************************************
//******************************************************************
void __cdecl DEBUG(const char * pszFmt,...)
{
if (pszFmt)
{
va_list args;
va_start(args,pszFmt);
app_debug_msg(pszFmt,args);
va_end(args);
}
}
void __cdecl FATAL(const char * pszFmt,...)
{
if (pszFmt)
{
va_list args;
va_start(args,pszFmt);
app_debug_msg(pszFmt,args);
va_end(args);
}
exit(123);
}
//******************************************************************
char *LoadFileInMem(const char * pszName)
{
HANDLE FileHandle;
DWORD SizeRead;
char *Buffer;
char TName[256];
int Size;
sprintf(TName,pszName);
if( (FileHandle = CreateFile(TName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == INVALID_HANDLE_VALUE )
{
FATAL("ERROR : Could not open file %s.",TName);
return NULL;
}
else
{
Size = GetFileSize(FileHandle,NULL);
if( (Buffer=(char*)malloc(Size))==NULL ) {printf("Out of memory.\n");exit(123);}
ReadFile(FileHandle,(void*)Buffer,Size,&SizeRead,NULL);
CloseHandle(FileHandle);
}
return Buffer;
}
//******************************************************************
int FindFileSize(const char * FileName)
{
HANDLE FileHandle;
DWORD Size;
char TName[256];
sprintf(TName,FileName);
if( (FileHandle = CreateFile(TName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == INVALID_HANDLE_VALUE )
{
FATAL("ERROR : Could not open file %s.",TName);
return (0);
}
else
{
Size = GetFileSize(FileHandle,NULL);
CloseHandle(FileHandle);
}
return (Size);
}
int FindFileSizeAlign(const char * FileName)
{
int Size=FindFileSize(FileName);
Size = ((Size + 3) & 0xfffffffc);
return(Size);
}
//******************************************************************
// Read pre-defined script file
//******************************************************************
int IsWhiteSpace(char c)
{
if (c==' ') return(1);
if (c==TAB) return(1);
if (c==0xd) return(1);
if (c==0xa) return(1);
return(0);
}
//******************************************************************
char *SkipWhiteSpace(char *Ptr)
{
while (IsWhiteSpace(*Ptr)) Ptr++;
return(Ptr);
}
//******************************************************************
char *GotoNextLine(char *Ptr)
{
while (*Ptr!=EOL) Ptr++;
return(Ptr+2);
}
//******************************************************************
void ReadScript()
{
char *Ptr,*EndPtr;
int Size;
sInFile InFile;
Script = (char *)LoadFileInMem( ScriptFile);
Size = FindFileSize(ScriptFile);
Ptr=Script;
EndPtr=Ptr+Size;
while (Ptr<EndPtr)
{
Ptr=SkipWhiteSpace(Ptr);
if (Ptr>=EndPtr) return;
if (*Ptr==COMMENT)
{ // Comment
Ptr=GotoNextLine(Ptr);
}
else
{
int i=0;
InFile.Chunks=0;
while (!IsWhiteSpace(*Ptr) && Ptr<EndPtr) InFile.Name[i++]=*Ptr++;
InFile.Name[i]=0;
strupr(InFile.Name);
FileList.push_back(InFile);
// printf("%s\n",InFile.Name);
}
}
}
//******************************************************************
//*** Get File Sizes ***********************************************
//******************************************************************
void GetFileSizes()
{
int FileCount=FileList.size();
int LangCount=LangList.size();
char FileName[256];
// DEBUG( "Parsing Files");
for (int File=0; File<FileCount; File++)
{
sInFile &ThisFile=FileList[File];
ThisFile.Chunks=0;
for (int Lang=0; Lang<LangCount; Lang++)
{
sLang &ThisLang=LangList[Lang];
int ThisFileSize;
int ThisChunkSize;
sprintf(FileName,"%s\\%c%s.%s", ThisLang.Dir, ThisLang.Prefix, ThisFile.Name, InFileEXT);
ThisFileSize=FindFileSize(FileName);
ThisChunkSize=(ThisFileSize+(CHUNKSIZE-1))/CHUNKSIZE;
if (ThisFile.Chunks<ThisChunkSize) ThisFile.Chunks=ThisChunkSize;
}
}
}
//******************************************************************
//*** Write Data ***************************************************
//******************************************************************
void WriteData(sLang &ThisLang)
{
char *Buffer;
char FileName[256];
FILE *OutFile;
char Blank[CHUNKSIZE];
int FileCount=FileList.size();
memset( Blank, 0xBA, CHUNKSIZE ); // clear Blank Buffer
sprintf(FileName,"%s%c%s.%s",OutDir,ThisLang.Prefix ,fname,OutFileEXT);
OutFile= fopen( FileName,"wb" );
if(!OutFile)
FATAL( "Could not write %s", FileName);
else
DEBUG( "Created File - %s", FileName);
for (int File=0; File<FileCount; File++)
{
sInFile &ThisFile=FileList[File];
int ThisFileSize;
sprintf(FileName,"%s\\%c%s.%s", ThisLang.Dir, ThisLang.Prefix, ThisFile.Name, InFileEXT);
Buffer=LoadFileInMem(FileName);
ThisFileSize=FindFileSize(FileName);
fwrite( Buffer, 1, ThisFileSize, OutFile);
fwrite( Blank, 1, (ThisFile.Chunks*CHUNKSIZE)-ThisFileSize, OutFile); // Write Pad
fwrite( Blank, 1, CHUNKSIZE, OutFile); // Force Pad
ThisFile.Offset=ftell(OutFile);
free(Buffer);
}
fclose(OutFile);
}
//******************************************************************
//*** Write Header File ********************************************
//******************************************************************
static char s_illegalChars[] = "\\/!<21>$%^&*()+-=-:. ";
static int s_nbChars = sizeof(s_illegalChars);
void convertIllegalChar( char *c )
{
for (int i=0;i<s_nbChars;i++)
{
if (*c == s_illegalChars[i]) *c = '_';
}
}
//******************************************************************
void ConvertString(char *Str) {while(*Str) convertIllegalChar(Str++);}
//******************************************************************
void WriteHeader(sLang &ThisLang)
{
FILE *OutFile;
char HdrStr[256];
char EqStr[256];
int FileCount=FileList.size();
int Offset=0;
sprintf(HdrStr,"__%s_SPEECH_DEFINES_H__",strupr(fname));
sprintf(EqStr,"%s_SPEECH_",strupr(fname));
OutFile= fopen( IncludeFilename,"wt" );
if(!OutFile)
FATAL( "Could not write %s", IncludeFilename);
else
DEBUG( "Created File - %s", IncludeFilename);
fprintf( OutFile, "#ifndef %s\n",HdrStr);
fprintf( OutFile, "#define %s\n\n",HdrStr);
fprintf( OutFile, "enum %sENUMS\n" ,EqStr);
fprintf( OutFile, "{\n" );
for (int File=0; File<FileCount; File++)
{
sInFile &ThisFile=FileList[File];
ConvertString(ThisFile.Name);
fprintf( OutFile, "%s%s = 0x%x,\n", "SPEECH_",ThisFile.Name, Offset+(BankNo<<BANK_SHIFT));
Offset+=ThisFile.Chunks+1; // +1 for pad
}
fprintf( OutFile, "};\n" );
fprintf( OutFile, "#endif\n" );
fclose(OutFile);
}
//***************************************************
//***************************************************
//***************************************************
int main(int argc, char *argv[])
{
int CmdError=0;
// Parse Input
for (int Loop=1;Loop<argc;Loop++)
{
char *StrPtr=argv[Loop];
if (StrPtr[0]!='-') CmdError=1;
StrPtr++;
switch(StrPtr[0])
{
case 'o': // Output
OutDir=StrPtr+1;
break;
case 'd': // Add In Dir
{
sLang Dir;
Dir.Prefix=StrPtr[1];
Dir.Dir=StrPtr+2;
LangList.push_back(Dir);
DEBUG("Added Lang:%s",Dir.Dir);
}
break;
case 's': // script
ScriptFile=StrPtr+1;
break;
case 'i': // script
IncFileSet=1;
strcpy(IncludeFilename,StrPtr+1);
break;
case 'b': // script
BankNo=atoi(StrPtr+1);
break;
default:
printf("Unknown Param [%s]\n",StrPtr);
break;
}
}
if(!ScriptFile || !LangList.size())
{
DEBUG("Error in command line");
DEBUG("Usage : MkSpeech");
DEBUG(" -d\tAdd Dir (Prefix & Dir= -dPddddd)");
DEBUG(" -o\tOut Dir");
DEBUG(" -s\tScript");
DEBUG(" -I\tHeaderFile");
DEBUG(" -B\tBankNo");
return(0);
}
_splitpath( ScriptFile, drive, dir, fname, ext );
if (!IncFileSet) sprintf(IncludeFilename,"%s%s.h",fname,"_Speech",OutFileEXT);
ReadScript();
// DEBUG( "Script Read.");
GetFileSizes();
int LangCount=LangList.size();
for (int Lang=0;Lang<LangCount; Lang++) WriteData(LangList[Lang]);
WriteHeader(LangList[0]);
DEBUG("Success.");
return(0);
}