692 lines
14 KiB
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;
|
|
}
|