/* 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 #include #include #include #include #include #include #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 ; iname , 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;isize) { 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 ; iname , 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;iname); 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" " \n" " \n" " .\n" " .\n" " .\n" //" \n" //" \n" //" \n" //" \n" //" \n" //" \n" //" \n" //" \n" " \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; }