RTSMAKER.C 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. /*
  2. Copyright (C) 1994-1995 Apogee Software, Ltd.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #define VERSION "2.0"
  16. /*
  17. =============================================================================
  18. RTSMAKER
  19. =============================================================================
  20. */
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <io.h>
  24. #include <fcntl.h>
  25. #include <sys/stat.h>
  26. #include <string.h>
  27. #include <direct.h>
  28. #include "cmdlib.h"
  29. #include "scriplib.h"
  30. #define MAXSOUNDS 10
  31. //================
  32. //
  33. // wad file types
  34. //
  35. //================
  36. typedef struct
  37. {
  38. long filepos;
  39. long size;
  40. char name[8];
  41. } lumpinfo_t;
  42. typedef struct
  43. {
  44. char identification[4];
  45. long numlumps;
  46. long infotableofs;
  47. } wadinfo_t;
  48. //==========================================================================
  49. char destpath[MAXPATH];
  50. wadinfo_t newwad; // the file being written out
  51. lumpinfo_t *newlumps;
  52. int newhandle;
  53. lumpinfo_t *lump_p; // wadlumps[lumpon]
  54. int lumpon; // current lump
  55. char loadwadpath[MAXPATH];
  56. char lumppath[MAXPATH];
  57. int datahandle; // can be an individual file or a WAD
  58. wadinfo_t loadwad; // a WAD file to look for lumps in
  59. lumpinfo_t *wadlumps;
  60. lumpinfo_t *wadlump_p; // info on lump to copy
  61. boolean inwadfile;
  62. boolean outputnamed;
  63. char sourcepath[MAXPATH];
  64. char defaultdestpath[MAXPATH];
  65. int lumpscopied; // number of copy operations done
  66. char scriptfilename[MAXPATH];
  67. //============================================================================
  68. /*
  69. ================
  70. =
  71. = OpenLump
  72. =
  73. = If in a wad file, lseeks to the start of the lump
  74. =
  75. = If a separate file, sets inputhandle to the open file
  76. =
  77. ================
  78. */
  79. void OpenLump (void)
  80. {
  81. int i;
  82. char lumpname[9];
  83. #if 0
  84. if (inwadfile)
  85. {
  86. lumpname[8] = 0;
  87. strncpy (lumpname, lump_p->name, 8);
  88. //
  89. // set wadlump_p to the lumpinfo in the open wad file
  90. //
  91. wadlump_p = wadlumps;
  92. for (i=0 ; i<loadwad.numlumps ; i++, wadlump_p++)
  93. if (strncmp( lump_p->name , wadlump_p->name, 8) == 0)
  94. break;
  95. if (i == loadwad.numlumps)
  96. Error ("lump %s is not in wad file %s\n",lumpname,lumppath);
  97. strcpy (lumppath, loadwadpath);
  98. strcat (lumppath, " : ");
  99. strcat (lumppath, lumpname);
  100. }
  101. else
  102. #endif
  103. {
  104. //
  105. // open the file on disk
  106. //
  107. datahandle = SafeOpenRead (lumppath);
  108. }
  109. }
  110. /*
  111. =================
  112. =
  113. = CopyLump
  114. =
  115. =================
  116. */
  117. #define MAXCOPYSIZE (16384)
  118. void CopyLump (void)
  119. {
  120. long size;
  121. long tempsize;
  122. byte *buffer;
  123. #if 0
  124. if (inwadfile)
  125. {
  126. lseek (datahandle, LittleLong (wadlump_p->filepos) ,SEEK_SET);
  127. size = LittleLong (wadlump_p->size);
  128. }
  129. else
  130. #endif
  131. size = filelength (datahandle);
  132. printf ("%4i = %s (%lu bytes)\n",lumpon,lumppath,size);
  133. lump_p->filepos = LittleLong (tell(newhandle));
  134. lump_p->size = LittleLong (size);
  135. buffer = SafeMalloc (MAXCOPYSIZE);
  136. while (size>0)
  137. {
  138. tempsize=MAXCOPYSIZE;
  139. if (tempsize>size)
  140. tempsize=size;
  141. SafeRead (datahandle, buffer, tempsize);
  142. SafeWrite (newhandle, buffer, tempsize);
  143. size -= tempsize;
  144. }
  145. SafeFree (buffer);
  146. #if 0
  147. if (!inwadfile)
  148. close (datahandle);
  149. #endif
  150. lumpon++;
  151. lump_p++;
  152. lumpscopied++;
  153. }
  154. /*
  155. =============================================================================
  156. SCRIPT COMMANDS
  157. =============================================================================
  158. */
  159. /*
  160. =================
  161. =
  162. = UnpackRTS
  163. =
  164. =================
  165. */
  166. void UnpackRTS (char * filename)
  167. {
  168. long i;
  169. long handle;
  170. lumpinfo_t * lptr;
  171. long size;
  172. long tempsize;
  173. byte tempbyte;
  174. byte * buffer;
  175. char tempname[80];
  176. //
  177. // open it and read in header / lump directory
  178. //
  179. datahandle = SafeOpenRead (filename);
  180. SafeRead (datahandle,&loadwad,sizeof(loadwad));
  181. loadwad.numlumps = LittleLong (loadwad.numlumps);
  182. loadwad.infotableofs = LittleLong (loadwad.infotableofs);
  183. if (strncmp(loadwad.identification,"IWAD",4))
  184. Error ("Wad file %s doesn't have IWAD id\n",lumppath);
  185. lseek (datahandle , loadwad.infotableofs , SEEK_SET);
  186. wadlumps = SafeMalloc ( loadwad.numlumps*sizeof(lumpinfo_t) );
  187. SafeRead (datahandle, wadlumps , loadwad.numlumps*sizeof(lumpinfo_t));
  188. for (i=0;i<loadwad.numlumps;i++)
  189. {
  190. lptr = &wadlumps[i];
  191. if (!lptr->size)
  192. {
  193. continue;
  194. }
  195. lseek (datahandle, LittleLong (lptr->filepos) ,SEEK_SET);
  196. size = LittleLong (lptr->size);
  197. memset(tempname,0,sizeof(tempname));
  198. strncpy(tempname,lptr->name,8);
  199. SafeRead (datahandle, &tempbyte, 1);
  200. lseek (datahandle, LittleLong (lptr->filepos) ,SEEK_SET);
  201. if (tempbyte == 'C')
  202. {
  203. strcat(tempname,".voc");
  204. }
  205. else
  206. {
  207. strcat(tempname,".wav");
  208. }
  209. printf(" writing %s\n",tempname);
  210. handle = SafeOpenWrite (tempname);
  211. buffer = SafeMalloc (MAXCOPYSIZE);
  212. while (size>0)
  213. {
  214. tempsize=MAXCOPYSIZE;
  215. if (tempsize>size)
  216. tempsize=size;
  217. SafeRead (datahandle, buffer, tempsize);
  218. SafeWrite (handle, buffer, tempsize);
  219. size -= tempsize;
  220. }
  221. SafeFree (buffer);
  222. close(handle);
  223. }
  224. close(datahandle);
  225. }
  226. #if 0
  227. /*
  228. =================
  229. =
  230. = CmdCloseWad
  231. =
  232. =================
  233. */
  234. void CmdCloseWad (void)
  235. {
  236. if (!inwadfile)
  237. Error ("$CLOSEWAD issued without an open wad file\n");
  238. close (datahandle);
  239. SafeFree (wadlumps);
  240. inwadfile = false;
  241. }
  242. /*
  243. =================
  244. =
  245. = CmdOpenWad
  246. =
  247. =================
  248. */
  249. void CmdOpenWad (void)
  250. {
  251. if (inwadfile)
  252. CmdCloseWad ();
  253. //
  254. // get and qualify wad file name
  255. //
  256. GetToken (false);
  257. strcpy (loadwadpath, token);
  258. DefaultExtension (loadwadpath, ".wad");
  259. DefaultPath (loadwadpath, sourcepath);
  260. //
  261. // open it and read in header / lump directory
  262. //
  263. datahandle = SafeOpenRead (loadwadpath);
  264. SafeRead (datahandle,&loadwad,sizeof(loadwad));
  265. loadwad.numlumps = LittleLong (loadwad.numlumps);
  266. loadwad.infotableofs = LittleLong (loadwad.infotableofs);
  267. if (strncmp(loadwad.identification,"IWAD",4))
  268. Error ("Wad file %s doesn't have IWAD id\n",lumppath);
  269. lseek (datahandle , loadwad.infotableofs , SEEK_SET);
  270. wadlumps = SafeMalloc ( loadwad.numlumps*sizeof(lumpinfo_t) );
  271. SafeRead (datahandle, wadlumps , loadwad.numlumps*sizeof(lumpinfo_t));
  272. inwadfile = true;
  273. }
  274. /*
  275. =================
  276. =
  277. = CmdShootWad
  278. =
  279. = Copies every lump in a wad file into the output
  280. =
  281. =================
  282. */
  283. void CmdShootWad (void)
  284. {
  285. int i;
  286. int start,end;
  287. CmdOpenWad ();
  288. start = lseek (newhandle , 0, SEEK_CUR);
  289. for (i=0 ; i<loadwad.numlumps ; i++)
  290. {
  291. strncpy (lump_p->name , wadlumps[i].name , 8);
  292. OpenLump ();
  293. CopyLump ();
  294. }
  295. end = lseek (newhandle , 0, SEEK_CUR);
  296. CmdCloseWad ();
  297. }
  298. /*
  299. ===================
  300. =
  301. = CmdLabel
  302. =
  303. ===================
  304. */
  305. void CmdLabel (void)
  306. {
  307. GetToken (false);
  308. lump_p->filepos = 0;
  309. lump_p->size = 0;
  310. strupr (token);
  311. strncpy( lump_p->name, token, 8);
  312. lumpon++;
  313. lump_p++;
  314. }
  315. #endif
  316. /*
  317. ===================
  318. =
  319. = AddLabel
  320. =
  321. ===================
  322. */
  323. void AddLabel ( char * string )
  324. {
  325. lump_p->filepos = 0;
  326. lump_p->size = 0;
  327. strupr (token);
  328. strncpy( lump_p->name, string, 8);
  329. lumpon++;
  330. lump_p++;
  331. }
  332. /*
  333. =====================
  334. =
  335. = CmdRTSName
  336. =
  337. =====================
  338. */
  339. void CmdRTSName (char *name)
  340. {
  341. //
  342. // get the output filename
  343. //
  344. strcpy (destpath,name);
  345. DefaultPath (destpath, defaultdestpath);
  346. DefaultExtension (destpath, ".RTS");
  347. printf ("Output rts file: %s\n",destpath);
  348. newhandle = SafeOpenWrite (destpath);
  349. newwad.numlumps = 0;
  350. strncpy (newwad.identification, "IWAD", 4);
  351. //
  352. // allocate space for the lump directory
  353. //
  354. newlumps = SafeMalloc (0x2000);
  355. lump_p = newlumps;
  356. lumpon = 0;
  357. //
  358. // position the file pointer to begin writing data
  359. //
  360. // leave space in the data file for the header
  361. lseek (newhandle,sizeof(newwad),SEEK_SET);
  362. }
  363. //==========================================================================
  364. #if 0
  365. /*
  366. ================
  367. =
  368. = CheckCommands
  369. =
  370. ================
  371. */
  372. boolean CheckCommands (void)
  373. {
  374. if (token[0] != '$')
  375. return false;
  376. //
  377. // link commands
  378. //
  379. if (!strcmpi(token,"$WADNAME") )
  380. {
  381. GetToken (false);
  382. CmdWadName (token);
  383. return true;
  384. }
  385. if (!strcmpi(token,"$OPENWAD") )
  386. {
  387. CmdOpenWad ();
  388. return true;
  389. }
  390. if (!strcmpi(token,"$SHOOTWAD") )
  391. {
  392. CmdShootWad ();
  393. return true;
  394. }
  395. if (!strcmpi(token,"$CLOSEWAD") )
  396. {
  397. CmdCloseWad ();
  398. return true;
  399. }
  400. if (!strcmpi(token,"$LABEL") )
  401. {
  402. CmdLabel ();
  403. return true;
  404. }
  405. Error ("Unrocognized command %s\n",token);
  406. return false;
  407. }
  408. #endif
  409. /*
  410. =============================================================================
  411. MAIN LOOP
  412. =============================================================================
  413. */
  414. /*
  415. ===================
  416. =
  417. = ProcessScript
  418. =
  419. ===================
  420. */
  421. void ProcessScript (void)
  422. {
  423. int i;
  424. lumpscopied = 0;
  425. outputnamed = false;
  426. //
  427. // get name of rts file
  428. //
  429. GetToken (true);
  430. CmdRTSName (token);
  431. // start of remote sound pack
  432. AddLabel ("REMOSTRT");
  433. for (i=0;i<MAXSOUNDS;i++)
  434. {
  435. GetToken (true);
  436. if (endofscript)
  437. break; // broke prematurely
  438. strcpy (lumppath,token);
  439. DefaultPath (lumppath,sourcepath);
  440. DefaultExtension (lumppath,".voc");
  441. ExtractFileBase (lumppath,lump_p->name);
  442. OpenLump (); // Find the lump data, either in a seperate file or in the comp file
  443. CopyLump (); // copy the lump to the output wad
  444. }
  445. if (i!=MAXSOUNDS)
  446. {
  447. unlink(destpath);
  448. Error("Only %d of %d vocs were specified in the RTS script file %s\n", i, MAXSOUNDS, &scriptfilename[0]);
  449. }
  450. // end of remote sound pack
  451. AddLabel ("REMOSTOP");
  452. }
  453. /*
  454. ===================
  455. =
  456. = WriteDirectory
  457. =
  458. ===================
  459. */
  460. void WriteDirectory (void)
  461. {
  462. //
  463. // write lumpinfo table
  464. //
  465. newwad.numlumps = LittleLong (lumpon);
  466. newwad.infotableofs = LittleLong (tell(newhandle));
  467. write (newhandle,newlumps, lumpon*sizeof(lumpinfo_t));
  468. //
  469. // write wadinfo
  470. //
  471. lseek (newhandle,0,SEEK_SET);
  472. write (newhandle,&newwad,sizeof(newwad));
  473. close (newhandle);
  474. }
  475. /*
  476. ===================
  477. =
  478. = main
  479. =
  480. ===================
  481. */
  482. int main (int argc, char **argv)
  483. {
  484. int i;
  485. printf ("\nRTSMAKER "VERSION" Copyright (c) 1996 3D Realms Entertainment.\n\n");
  486. //
  487. // check for help
  488. //
  489. if (CheckParm ("?") || (argc==1))
  490. {
  491. printf (
  492. "Usage: RTSMAKER -u(npack) [nameofscriptfile]\n\n"
  493. "RTS files are Remote-Ridicule (tm) sound files used in the multi-\n"
  494. "player modes of Duke Nukem 3D and Rise of the Triad.\n\n"
  495. "Duke Nukem 3D\n"
  496. "To use a different RTS file in Duke Nukem 3D, select 'Change RTS File'\n"
  497. "from the Modem, Network, or Serial Game menus in SETUP.EXE.\n\n"
  498. "Rise of the Triad\n"
  499. "To use a different RTS file in Rise of the Triad, select USE MODIFIED\n"
  500. "STUFF and CHOOSE REMOTE PLAYER SOUNDS from SETUP.EXE.\n\n"
  501. "SCRIPT FILE FORMAT:\n"
  502. " <Name of RTS file>\n"
  503. " <VOC or WAV file 1>\n"
  504. " .\n"
  505. " .\n"
  506. " .\n"
  507. //" <VOC or WAV file 2>\n"
  508. //" <VOC or WAV file 3>\n"
  509. //" <VOC or WAV file 4>\n"
  510. //" <VOC or WAV file 5>\n"
  511. //" <VOC or WAV file 6>\n"
  512. //" <VOC or WAV file 7>\n"
  513. //" <VOC or WAV file 8>\n"
  514. //" <VOC or WAV file 9>\n"
  515. " <VOC or WAV file 10>\n"
  516. " ';' can be used for comments\n"
  517. //"'sample.txt' is provided as an example."
  518. );
  519. exit (1);
  520. }
  521. i=CheckParm ("U");
  522. if (i)
  523. {
  524. printf ("Unpacking-> %s\n",argv[i+1]);
  525. UnpackRTS (argv[i+1]);
  526. exit(0);
  527. }
  528. //
  529. // get source directory for data files
  530. //
  531. getcwd (sourcepath,MAXPATH);
  532. if (sourcepath[strlen(sourcepath)-1] != '\\')
  533. strcat (sourcepath,"\\");
  534. printf ("Source directory : %s\n",sourcepath);
  535. //
  536. // get destination directory for link file
  537. //
  538. getcwd (defaultdestpath,MAXPATH);
  539. if (defaultdestpath[strlen(defaultdestpath)-1] != '\\')
  540. strcat (defaultdestpath,"\\");
  541. printf ("Destination directory: %s\n",defaultdestpath);
  542. //
  543. // get script file
  544. //
  545. strcpy (scriptfilename,argv[1]);
  546. printf ("Script file : %s\n",scriptfilename);
  547. LoadScriptFile (scriptfilename);
  548. //
  549. // start doing stuff
  550. //
  551. ProcessScript ();
  552. WriteDirectory ();
  553. printf ("\nAll VOC and WAV files grabbed into RTS file %s\n",destpath);
  554. return 0;
  555. }