rott/rtsmaker/RTSMAKER.C

692 lines
14 KiB
C

/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define VERSION "2.0"
/*
=============================================================================
RTSMAKER
=============================================================================
*/
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <direct.h>
#include "cmdlib.h"
#include "scriplib.h"
#define MAXSOUNDS 10
//================
//
// wad file types
//
//================
typedef struct
{
long filepos;
long size;
char name[8];
} lumpinfo_t;
typedef struct
{
char identification[4];
long numlumps;
long infotableofs;
} wadinfo_t;
//==========================================================================
char destpath[MAXPATH];
wadinfo_t newwad; // the file being written out
lumpinfo_t *newlumps;
int newhandle;
lumpinfo_t *lump_p; // wadlumps[lumpon]
int lumpon; // current lump
char loadwadpath[MAXPATH];
char lumppath[MAXPATH];
int datahandle; // can be an individual file or a WAD
wadinfo_t loadwad; // a WAD file to look for lumps in
lumpinfo_t *wadlumps;
lumpinfo_t *wadlump_p; // info on lump to copy
boolean inwadfile;
boolean outputnamed;
char sourcepath[MAXPATH];
char defaultdestpath[MAXPATH];
int lumpscopied; // number of copy operations done
char scriptfilename[MAXPATH];
//============================================================================
/*
================
=
= OpenLump
=
= If in a wad file, lseeks to the start of the lump
=
= If a separate file, sets inputhandle to the open file
=
================
*/
void OpenLump (void)
{
int i;
char lumpname[9];
#if 0
if (inwadfile)
{
lumpname[8] = 0;
strncpy (lumpname, lump_p->name, 8);
//
// set wadlump_p to the lumpinfo in the open wad file
//
wadlump_p = wadlumps;
for (i=0 ; i<loadwad.numlumps ; i++, wadlump_p++)
if (strncmp( lump_p->name , wadlump_p->name, 8) == 0)
break;
if (i == loadwad.numlumps)
Error ("lump %s is not in wad file %s\n",lumpname,lumppath);
strcpy (lumppath, loadwadpath);
strcat (lumppath, " : ");
strcat (lumppath, lumpname);
}
else
#endif
{
//
// open the file on disk
//
datahandle = SafeOpenRead (lumppath);
}
}
/*
=================
=
= CopyLump
=
=================
*/
#define MAXCOPYSIZE (16384)
void CopyLump (void)
{
long size;
long tempsize;
byte *buffer;
#if 0
if (inwadfile)
{
lseek (datahandle, LittleLong (wadlump_p->filepos) ,SEEK_SET);
size = LittleLong (wadlump_p->size);
}
else
#endif
size = filelength (datahandle);
printf ("%4i = %s (%lu bytes)\n",lumpon,lumppath,size);
lump_p->filepos = LittleLong (tell(newhandle));
lump_p->size = LittleLong (size);
buffer = SafeMalloc (MAXCOPYSIZE);
while (size>0)
{
tempsize=MAXCOPYSIZE;
if (tempsize>size)
tempsize=size;
SafeRead (datahandle, buffer, tempsize);
SafeWrite (newhandle, buffer, tempsize);
size -= tempsize;
}
SafeFree (buffer);
#if 0
if (!inwadfile)
close (datahandle);
#endif
lumpon++;
lump_p++;
lumpscopied++;
}
/*
=============================================================================
SCRIPT COMMANDS
=============================================================================
*/
/*
=================
=
= UnpackRTS
=
=================
*/
void UnpackRTS (char * filename)
{
long i;
long handle;
lumpinfo_t * lptr;
long size;
long tempsize;
byte tempbyte;
byte * buffer;
char tempname[80];
//
// open it and read in header / lump directory
//
datahandle = SafeOpenRead (filename);
SafeRead (datahandle,&loadwad,sizeof(loadwad));
loadwad.numlumps = LittleLong (loadwad.numlumps);
loadwad.infotableofs = LittleLong (loadwad.infotableofs);
if (strncmp(loadwad.identification,"IWAD",4))
Error ("Wad file %s doesn't have IWAD id\n",lumppath);
lseek (datahandle , loadwad.infotableofs , SEEK_SET);
wadlumps = SafeMalloc ( loadwad.numlumps*sizeof(lumpinfo_t) );
SafeRead (datahandle, wadlumps , loadwad.numlumps*sizeof(lumpinfo_t));
for (i=0;i<loadwad.numlumps;i++)
{
lptr = &wadlumps[i];
if (!lptr->size)
{
continue;
}
lseek (datahandle, LittleLong (lptr->filepos) ,SEEK_SET);
size = LittleLong (lptr->size);
memset(tempname,0,sizeof(tempname));
strncpy(tempname,lptr->name,8);
SafeRead (datahandle, &tempbyte, 1);
lseek (datahandle, LittleLong (lptr->filepos) ,SEEK_SET);
if (tempbyte == 'C')
{
strcat(tempname,".voc");
}
else
{
strcat(tempname,".wav");
}
printf(" writing %s\n",tempname);
handle = SafeOpenWrite (tempname);
buffer = SafeMalloc (MAXCOPYSIZE);
while (size>0)
{
tempsize=MAXCOPYSIZE;
if (tempsize>size)
tempsize=size;
SafeRead (datahandle, buffer, tempsize);
SafeWrite (handle, buffer, tempsize);
size -= tempsize;
}
SafeFree (buffer);
close(handle);
}
close(datahandle);
}
#if 0
/*
=================
=
= CmdCloseWad
=
=================
*/
void CmdCloseWad (void)
{
if (!inwadfile)
Error ("$CLOSEWAD issued without an open wad file\n");
close (datahandle);
SafeFree (wadlumps);
inwadfile = false;
}
/*
=================
=
= CmdOpenWad
=
=================
*/
void CmdOpenWad (void)
{
if (inwadfile)
CmdCloseWad ();
//
// get and qualify wad file name
//
GetToken (false);
strcpy (loadwadpath, token);
DefaultExtension (loadwadpath, ".wad");
DefaultPath (loadwadpath, sourcepath);
//
// open it and read in header / lump directory
//
datahandle = SafeOpenRead (loadwadpath);
SafeRead (datahandle,&loadwad,sizeof(loadwad));
loadwad.numlumps = LittleLong (loadwad.numlumps);
loadwad.infotableofs = LittleLong (loadwad.infotableofs);
if (strncmp(loadwad.identification,"IWAD",4))
Error ("Wad file %s doesn't have IWAD id\n",lumppath);
lseek (datahandle , loadwad.infotableofs , SEEK_SET);
wadlumps = SafeMalloc ( loadwad.numlumps*sizeof(lumpinfo_t) );
SafeRead (datahandle, wadlumps , loadwad.numlumps*sizeof(lumpinfo_t));
inwadfile = true;
}
/*
=================
=
= CmdShootWad
=
= Copies every lump in a wad file into the output
=
=================
*/
void CmdShootWad (void)
{
int i;
int start,end;
CmdOpenWad ();
start = lseek (newhandle , 0, SEEK_CUR);
for (i=0 ; i<loadwad.numlumps ; i++)
{
strncpy (lump_p->name , wadlumps[i].name , 8);
OpenLump ();
CopyLump ();
}
end = lseek (newhandle , 0, SEEK_CUR);
CmdCloseWad ();
}
/*
===================
=
= CmdLabel
=
===================
*/
void CmdLabel (void)
{
GetToken (false);
lump_p->filepos = 0;
lump_p->size = 0;
strupr (token);
strncpy( lump_p->name, token, 8);
lumpon++;
lump_p++;
}
#endif
/*
===================
=
= AddLabel
=
===================
*/
void AddLabel ( char * string )
{
lump_p->filepos = 0;
lump_p->size = 0;
strupr (token);
strncpy( lump_p->name, string, 8);
lumpon++;
lump_p++;
}
/*
=====================
=
= CmdRTSName
=
=====================
*/
void CmdRTSName (char *name)
{
//
// get the output filename
//
strcpy (destpath,name);
DefaultPath (destpath, defaultdestpath);
DefaultExtension (destpath, ".RTS");
printf ("Output rts file: %s\n",destpath);
newhandle = SafeOpenWrite (destpath);
newwad.numlumps = 0;
strncpy (newwad.identification, "IWAD", 4);
//
// allocate space for the lump directory
//
newlumps = SafeMalloc (0x2000);
lump_p = newlumps;
lumpon = 0;
//
// position the file pointer to begin writing data
//
// leave space in the data file for the header
lseek (newhandle,sizeof(newwad),SEEK_SET);
}
//==========================================================================
#if 0
/*
================
=
= CheckCommands
=
================
*/
boolean CheckCommands (void)
{
if (token[0] != '$')
return false;
//
// link commands
//
if (!strcmpi(token,"$WADNAME") )
{
GetToken (false);
CmdWadName (token);
return true;
}
if (!strcmpi(token,"$OPENWAD") )
{
CmdOpenWad ();
return true;
}
if (!strcmpi(token,"$SHOOTWAD") )
{
CmdShootWad ();
return true;
}
if (!strcmpi(token,"$CLOSEWAD") )
{
CmdCloseWad ();
return true;
}
if (!strcmpi(token,"$LABEL") )
{
CmdLabel ();
return true;
}
Error ("Unrocognized command %s\n",token);
return false;
}
#endif
/*
=============================================================================
MAIN LOOP
=============================================================================
*/
/*
===================
=
= ProcessScript
=
===================
*/
void ProcessScript (void)
{
int i;
lumpscopied = 0;
outputnamed = false;
//
// get name of rts file
//
GetToken (true);
CmdRTSName (token);
// start of remote sound pack
AddLabel ("REMOSTRT");
for (i=0;i<MAXSOUNDS;i++)
{
GetToken (true);
if (endofscript)
break; // broke prematurely
strcpy (lumppath,token);
DefaultPath (lumppath,sourcepath);
DefaultExtension (lumppath,".voc");
ExtractFileBase (lumppath,lump_p->name);
OpenLump (); // Find the lump data, either in a seperate file or in the comp file
CopyLump (); // copy the lump to the output wad
}
if (i!=MAXSOUNDS)
{
unlink(destpath);
Error("Only %d of %d vocs were specified in the RTS script file %s\n", i, MAXSOUNDS, &scriptfilename[0]);
}
// end of remote sound pack
AddLabel ("REMOSTOP");
}
/*
===================
=
= WriteDirectory
=
===================
*/
void WriteDirectory (void)
{
//
// write lumpinfo table
//
newwad.numlumps = LittleLong (lumpon);
newwad.infotableofs = LittleLong (tell(newhandle));
write (newhandle,newlumps, lumpon*sizeof(lumpinfo_t));
//
// write wadinfo
//
lseek (newhandle,0,SEEK_SET);
write (newhandle,&newwad,sizeof(newwad));
close (newhandle);
}
/*
===================
=
= main
=
===================
*/
int main (int argc, char **argv)
{
int i;
printf ("\nRTSMAKER "VERSION" Copyright (c) 1996 3D Realms Entertainment.\n\n");
//
// check for help
//
if (CheckParm ("?") || (argc==1))
{
printf (
"Usage: RTSMAKER -u(npack) [nameofscriptfile]\n\n"
"RTS files are Remote-Ridicule (tm) sound files used in the multi-\n"
"player modes of Duke Nukem 3D and Rise of the Triad.\n\n"
"Duke Nukem 3D\n"
"To use a different RTS file in Duke Nukem 3D, select 'Change RTS File'\n"
"from the Modem, Network, or Serial Game menus in SETUP.EXE.\n\n"
"Rise of the Triad\n"
"To use a different RTS file in Rise of the Triad, select USE MODIFIED\n"
"STUFF and CHOOSE REMOTE PLAYER SOUNDS from SETUP.EXE.\n\n"
"SCRIPT FILE FORMAT:\n"
" <Name of RTS file>\n"
" <VOC or WAV file 1>\n"
" .\n"
" .\n"
" .\n"
//" <VOC or WAV file 2>\n"
//" <VOC or WAV file 3>\n"
//" <VOC or WAV file 4>\n"
//" <VOC or WAV file 5>\n"
//" <VOC or WAV file 6>\n"
//" <VOC or WAV file 7>\n"
//" <VOC or WAV file 8>\n"
//" <VOC or WAV file 9>\n"
" <VOC or WAV file 10>\n"
" ';' can be used for comments\n"
//"'sample.txt' is provided as an example."
);
exit (1);
}
i=CheckParm ("U");
if (i)
{
printf ("Unpacking-> %s\n",argv[i+1]);
UnpackRTS (argv[i+1]);
exit(0);
}
//
// get source directory for data files
//
getcwd (sourcepath,MAXPATH);
if (sourcepath[strlen(sourcepath)-1] != '\\')
strcat (sourcepath,"\\");
printf ("Source directory : %s\n",sourcepath);
//
// get destination directory for link file
//
getcwd (defaultdestpath,MAXPATH);
if (defaultdestpath[strlen(defaultdestpath)-1] != '\\')
strcat (defaultdestpath,"\\");
printf ("Destination directory: %s\n",defaultdestpath);
//
// get script file
//
strcpy (scriptfilename,argv[1]);
printf ("Script file : %s\n",scriptfilename);
LoadScriptFile (scriptfilename);
//
// start doing stuff
//
ProcessScript ();
WriteDirectory ();
printf ("\nAll VOC and WAV files grabbed into RTS file %s\n",destpath);
return 0;
}