deutex-4.4.902/0000755000324500032450000000000010305373426012573 5ustar aymaym00000000000000deutex-4.4.902/docsrc/0000755000324500032450000000000010305373425014047 5ustar aymaym00000000000000deutex-4.4.902/docsrc/README0000644000324500032450000000352410301444222014721 0ustar aymaym00000000000000DeuTex $VERSION DESCRIPTION DeuTex and DeuSF are programs than can do many things with Doom, Heretic, Hexen and Strife wad files such as extracting and inserting graphics, sounds, levels and other resources. See the manual for details (dtexman6.txt). BUILDING AND INSTALLING ON UNIX You need a reasonably standard Unix environment with a C compiler. The first step is to type ./configure If you need to install somewhere else than /usr/local, give ./configure the --prefix option. For example, to install in ~/deutex, ./configure --prefix ~/deutex The C compiler is auto-detected. If the auto-detection does not find your compiler, use the --cc option : ./configure --cc ~/mycc-1.2.3/mycc The default CFLAGS is "-O2 -Wall" for GCC, "-O" for other compilers. The default LDFLAGS is empty. To override these, you can use the --cflags and/or the --ldflags options. For example, ./configure --cflags '-O2 -m64' --ldflags '-m64' After ./configure completes successfully, type make Finally, type make install Note that you will need to type this last command as root if you're installing in /usr/local or some other "system" directory. BUILDING AND INSTALLING ON DOS See INSTALL. LEGAL DeuTex is Copyright Olivier Montanuy 1994-1995 and Copyright André Majorel 1999-2005 and available under the terms of version 2 of the GPL, except lzw.c which is Copyright David Koblas and others and available under the terms of the PBMPLUS license. See the LICENSE file. All trademarks are the property of their owners. CONTACT Home page : http://www.teaser.fr/~amajorel/deutex/ Doom questions : news:rec.games.computer.doom.editing DeuTex questions : The Yadex mailing list (http://www.teaser.fr/~amajorel/yadex/lists.html) -- AYM $SELF_DATE deutex-4.4.902/docsrc/changes.html0000644000324500032450000010364110305347506016353 0ustar aymaym00000000000000 History of changes for DeuTex

History of changes for DeuTex

DeuTex 4.4.902 (AYM 2005-08-31)
DeuTex 4.4.0 (AYM 2000-01-05)
DeuTex 4.3.0 (AYM 1999-12-24)
DeuTex 4.2.2 (AYM 1999-11-20) (not for public consumption)
DeuTex 4.2.1 (AYM 1999-11-16) (not for public consumption)
DeuTex 4.2.0 (AYM 1999-11-14)
DeuTex 4.1.0 (AYM 1999-11-01)
DeuTex 4.0.3 (AYM 1999-10-02)
DeuTex 4.0.2 (AYM 1999-09-19)
DeuTex 4.0.1 (AYM 1999-09-10)
DeuTex 4.0.0a3 (AYM 1999-09-05)
DeuTex 4.0.0a2 (AYM 1999-08-14)
DeuTex 4.0.0a1 (AYM 1999-08-12)
deutex-4.4.902/docsrc/deutex.60000644000324500032450000002076110304406340015432 0ustar aymaym00000000000000.\" This file is part of DeuTex. .\" .\" DeuTex incorporates code derived from DEU 5.21 that was put in the .\" public domain in 1994 by Raphaël Quinet and Brendon Wyber. .\" .\" DeuTex is Copyright © 1994-1995 Olivier Montanuy, .\" Copyright © 1999-2005 André Majorel. .\" .\" 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 library; if not, write to the Free Software Foundation, Inc., .\" 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. .\" .TH DEUTEX 6 $DATE "DeuTex $VERSION" .SH NAME deutex, deusf \- do things with wad files .SH SYNOPSIS .BR "deutex \-?" | \-h | \-help | \-\-help .br .B deutex \-\-version .br .B deutex \-man .br \fBdeutex\fP [\fIoptions\fP] .B \-add .I incomplete.wad out.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-af .I flats.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-append .I incomplete.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-as .I sprite.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-check .I in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-debug .RI [ in.gif ] .br \fBdeutex\fP [\fIoptions\fP] .B \-get .I entry .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-join .I incomplete.wad in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-make \fR[\fP\fIdirctivs.txt\fP\fR] \fP\fIout.wad\fP .br \fBdeutex\fP [\fIoptions\fP] .B \-merge .I in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-pkgfx .RI [ in.wad " [" out.txt ]] .br \fBdeutex\fP [\fIoptions\fP] .B \-pknormal .RI [ in.wad " [" out.txt ]] .br \fBdeutex\fP [\fIoptions\fP] .B \-restor\fP .br \fBdeutex\fP [\fIoptions\fP] .B \-usedidx .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-usedtex .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-unused .I in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-wadir .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-xtract .I in.wad .RI [ dirctivs.txt ] .br .BR "deusf \-?" | \-h | \-help | \-\-help .br .B deusf \-\-version .br .BI "deusf " options .br .SH DESCRIPTION DeuTex is a wad composer for Doom, Heretic, Hexen and Strife. It can be used to extract the lumps of a wad and save them as individual files or the reverse, and much more. .PP When extracting a lump to a file, it does not just copy the raw data, it converts it to an appropriate format (such as PPM for graphics, Sun audio for samples, etc.). Conversely, when it reads files for inclusion in pwads, it does the necessary conversions (for example, from PPM to Doom picture format). .PP DeuSF is a trimmed version of DeuTex that is used to merge sprites and flats from a pwad into an iwad, which is sometimes necessary because Doom and its breed do not handle sprites in pwads well. .PP See \fBdocsrc/dtexman6.txt\fP for more information on DeuTex and DeuSF. .SS Decomposing a wad To decompose a wad (i.e. extract its contents), use the \fB\-extract\fP (a.k.a. \fB\-xtract\fP) command. When decomposing a wad, DeuTex creates one file for each lump. The files are created in one of the following subdirectories of the working directory: \fBflats/\fP, \fBlumps/\fP, \fBmusics/\fP, \fBpatches/\fP, \fBsounds/\fP, \fBsprites/\fP, \fBtextures/\fP. The decomposing process also creates a very important file, \fBwadinfo.txt\fP, which will be used later when composing. .PP To extract the contents of the Doom II iwad, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-xtract\fP .fi .PP To extract the contents of a Doom II pwad named \fImywad.wad\fP, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-xtract mywad.wad\fP .fi .PP To extract only the sprites, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-sprites \-xtract\fP .fi .PP To extract only the sounds and save them as .voc, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-sounds \-voc \-xtract\fP .fi .SS Composing (building) a wad Composing is the symmetrical process. It's done with the three commands \fB\-build\fP, \fB\-create\fP and \fB\-make\fP, that are equivalent. Using \fBwadinfo.txt\fP and the files in flats/, lumps/, musics/, patches/, sounds/, sprites/ and textures/, DeuTex creates a new wad. .PP To create a new pwad named \fImywad.wad\fP, .nf .RS \fBdeutex \-doom2 /path/to/doom2.wad \-make mywad.wad\fP .RE .fi .PP To create a new iwad named \fImytc.wad\fP, .nf .RS \fBdeutex \-doom2 /path/to/doom2.wad \-iwad \-make mytc.wad\fP .RE .fi .SS Other operations DeuTex has many (too many ?) other commands like \fB\-join\fP, \fB\-merge\fP, \fB\-usedtex\fP etc. See \fBdocsrc/dtexman6.txt\fP for a full description. .SH OPTIONS $OPTIONS .SH DIAGNOSTICS All messages are identified by a unique code. Some messages are identical\ ; the code is useful to distinguish them. All codes have four characters\ ; two letters and two digits. The letters identify the part of the code where the message comes from, the digits give the message number within that area. In general, numbers are assigned so that messages that come from parts of the code that are executed earlier have lower numbers. .SH FILES .TP .IB dir /flats/ When extracting, flats are saved to this directory. When composing, flats are read from this directory. .TP .IB dir /graphics/ When extracting, graphics are saved to this directory. When composing, graphics are read from this directory. .TP .IB dir /levels/ When extracting, levels are saved to this directory. When composing, levels are read from this directory. .TP .IB dir /lumps/ When extracting, lumps are saved to this directory. When composing, lumps are read from this directory. .TP .IB dir /musics/ When extracting, musics are saved to this directory. When composing, musics are read from this directory. .TP .IB dir /patches/ When extracting, patches are saved to this directory. When composing, patches are read from this directory. .TP .IB dir /scripts/ When extracting, Strife scripts are saved to this directory. When composing, Strife scripts are read from this directory. .TP .IB dir /sneaps/ When extracting, Doom alpha sneaps are saved to this directory. When composing, Doom alpha sneaps are read from this directory. .TP .IB dir /sneats/ When extracting, Doom alpha sneats are saved to this directory. When composing, Doom alpha sneats are read from this directory. .TP .IB dir /sounds/ When extracting, sounds are saved to this directory. When composing, sounds are read from this directory. .TP .IB dir /sprites/ When extracting, sprites are saved to this directory. When composing, sprites are read from this directory. .TP .IB dir /textures/texture1.txt The \fBTEXTURE1\fP lump (all but Doom alpha 0.4 and 0.5). .TP .IB dir /textures/texture2.txt The \fBTEXTURE2\fP lump (all commercial iwads except Doom 2). .TP .IB dir /textures/textures.txt The \fBTEXTURES\fP lump (Doom alpha 0.4 and 0.5). .TP .IB dir /wadinfo.txt The default master file. .SH ENVIRONMENT .TP .B DOOMWADDIR The directory where the iwad resides. The value of this environment variable is overridden by \fB\-main\fP, \fB\-doom\fP and friends. .SH BUGS See \fBTODO\fP. .SH LEGAL DeuTex is copyright © 1994-1995 Olivier Montanuy, copyright © 1999-2005 André Majorel. .PP Most of this program is GPL'd but some of it is available under other licenses. 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 LICENSE for specific information and copyright notices. All trademarks are the property of their owners. .SH AUTHOR The original author of DeuTex is Olivier Montanuy . From 1994 to 1996, DeuTex was maintained by Olivier Montanuy with help from Per Allansson , James Bonfield , Sharon Bowles, Mark Mathews and Chuck Rossi. The original manual was written by Kevin McGrail . .PP As of version 4 (1999), the maintainer is André Majorel . .PP Questions and bug reports should be sent to the current maintainer, \fInot\fP to the original authors. .SH SEE ALSO .BR wadcat (6), .BR wadext (6), .BR wadext2 (6), .BR wadflat (6), .BR wadgc (6), .BR wadlc (6), .BR wadldc (6), .BR wadpatch (6), .BR wadsprit (6), .BR wadtex (6), .BR wadtxls (6), .BR xwadtools (6) deutex-4.4.902/docsrc/faq.html0000644000324500032450000000774210304601315015505 0ustar aymaym00000000000000 DeuTex FAQ

DeuTex FAQ

1. When I extract the contents of the Heretic iwad, why are CREDIT, E2END, FINAL1, FINAL2, HELP1, HELP2 and TITLE extracted into lumps/ and not into graphics/ ?

They're extracted into lumps/ because that's what they are. The graphics/ directory is for images that are in the in the so-called "picture" format, described in section [5-1] of the UDS (HTTP link). Those lumps are not in picture format, they're just straight bitmaps (320 × 200 pixels, 64,000 bytes).

The distinction may seem academic, but it isn't. If those lumps were extracted into graphics/, it would be impossible to compose your wad correctly afterwards. In the wad created by DeuTex, CREDIT and friends would be in the picture format while the engine expects them to be in the 64000-byte matrix format.

2. When I extract the contents of the Hexen iwad, why are CREDIT, FINALE1, FINALE2, FINALE3, HELP1, HELP2, INTERPIC and TITLE extracted into lumps/ and not into graphics/ ?

See question 1.

3. I've composed a wad. When I play it, the transparent areas in the graphics look opaque and blue or grey, like this :
Screenshot

This is what happens when you try to use DeuTex 4 on files extracted by DeuTex 3 or WinTex.

It happens because DeuTex 3 and WinTex use (0, 255, 255) (cyan) for transparent areas while DeuTex 4 uses (0, 47, 47) (dark blue-green). Therefore, what looks like a transparent pixel to DeuTex 3 and WinTex just looks like an opaque, cyan pixel to DeuTex 4. The closest match to cyan in the Doom palette is (115, 115, 255) (blue-mauve) so that's what you get.

Try one of the following :

  • convert your files to use (0, 47, 47) instead of (0, 255, 255),
  • recreate your files using DeuTex 4,
  • recreate your files using DeuTex 3 with the "-rgb 0 47 47" option,
  • recreate your files using WinTex using the appropriate option (if it exists),
  • when composing, give DeuTex 4 the "-rgb 0 255 255" option.
4. The musics are extracted into lumps/.

This has been fixed in version 4.4.

5. When composing, is there a way to include only the resources actually used by the levels ?

No. Though it would certainly be nice to have.


AYM 2005-08-29

deutex-4.4.902/docsrc/hackers_guide.html0000644000324500032450000000506210304554306017533 0ustar aymaym00000000000000 Hacker's guide

Hacker's guide

Endianness

Some files contain numbers that have a fixed endianness, independent from the endianness of the CPU DeuTex happens to run on. These call for some special treatment, as the C language has no provision for reading and writing integers otherwise than in the native endianness.

  • To read an integer from a file with a particular endianness, use fread_i16_le(), fread_i16_be(), fread_i32_le() and fread_i32_be(). The first argument is the file descriptor, the second argument is a pointer on a variable that will receive the value read from the file.

  • To write an integer to a file with a particular endianness, use fwrite_i16_le(), fwrite_i16_be(), fwrite_i32_le() and fwrite_i32_be(). The first argument is the file descriptor, the second argument is the value to write.

  • To read an integer with a particular endianness from a memory area, use read_i16_le(), read_i16_be(), read_i32_le() and read_i32_be(). The first argument is a pointer on the memory area, the second argument is a pointer on a variable that will receive the value read from the memory area. Alternatively, you can use the peek_i*() functions that take no second argument but instead return the read value.

  • To write an integer with a particular endianness to a memory area, use write_i16_le(), write_i16_be, write_i32_le() and write_i32_be(). The first argument is a pointer on the memory area, the second argument is the value to write.

Mnemonic to remember the arguments order : the object that has a defined endianness is considered central and therefore always comes first.

Here is some sample code and the result of running it.

fwrite_i32_be (stdout, 0x12345678);
fwrite_i32_le (stdout, 0x12345678);
fwrite_i16_be (stdout, 0xabcd);
fwrite_i16_le (stdout, 0xabcd);
12 34 56 78 78 56 34 12 AB CD CD AB
deutex-4.4.902/docsrc/readme.dos0000644000324500032450000000222510301444206016004 0ustar aymaym00000000000000DeuTex $VERSION - DOS binary distribution WHAT ARE DEUTEX AND DEUSF DeuTex and DeuSF are programs than can do many things with Doom, Heretic, Hexen and Strife wad files such as extracting and inserting graphics, sounds, levels and other resources. See the manual for details (dtexman6.txt). This is a binary distribution. It only contains a DOS pre-compiled executable and the user documentation. The source and the rest of the documentation are in deutex-$VERSION.tar.gz. INSTALLING Copy deutex.exe and deusf.exe in a directory of your PATH. LEGAL DeuTex is Copyright Olivier Montanuy 1994-1995 and Copyright André Majorel 1999-2005 and available under the terms of the GPL, except lzw.c which is Copyright David Koblas and others and available under the terms of the PBMPLUS license. See the LICENSE file. All trademarks are the property of their owners. CONTACT Home page : http://www.teaser.fr/~amajorel/deutex/ Doom questions : news:rec.games.computer.doom.editing DeuTex questions : The Yadex mailing list (http://www.teaser.fr/~amajorel/yadex/lists.html) -- AYM $SELF_DATE deutex-4.4.902/docsrc/todo.html0000644000324500032450000003510210305107536015701 0ustar aymaym00000000000000 To-do list for DeuTex

To-do list for DeuTex

Directives file

  • In the directives file and textures files, "include" directive to include the rest of another block/file.
  • In the directives file and textures files, allow references to environment variables (E.G. $E(name)).
  • In the directives file and textures files, allow user variables (E.G. $(name))
  • Make it easier to let a texture have a description identical to another texture
  • In the directives file, add a mean to import all/only named/all except named flats as patches.
  • In the directives file, add a mean to import all/only named/all except named patches as flats. This implies 1) accepting flats larger than 64×64 (by clipping) 2) converting transparent pixels to a certain colour (which one ?).
  • In the directives file, add a mean to automatically generate a texture for all/only named/all except named patches. The height of the automatic texture is 128, its width is the least power of two wide enough to contain the patch. The automatic texture is filled with the patch by tiling, starting from the top left corner. The name of the automatic texture is the name of the patch.
  • Wherever an image is imported, give the option of applying graphical transforms: crop, tile, rotate, mirror, roll, colour.
  • Wherever an image is imported, give the option of composing the image from several files. This would be particularly useful for flats, which cannot be composed from several patches like textures do. This might complicate the wadinfo.txt syntax, though.
  • Instead of allowing any and all characters in the script file, require them to be quoted. And, when doing -xtract, produce the script file with the appropriate quotes... Since, under Unix, the only characters that are not allowed in a file name are NUL and "/", I don't see why DeuTex should prevent users from extracting lumps with weird characters in their names. However, that might cause compatilibity problems with the DOS version.
  • When composing, warn about invalid sections (E.G. "[poo]").

Game support

  • Doom alpha GNUM[0-9] :
    • find name for 10x12, preferably ending in "p" (xxx),
    • implement IDENTxxx(),
    • add [xxx] section to wadinfo.txt,
    • make list of lumps that used to go in lumps/ and now go in xxx/ and put that in changes.html,
    • create corresponding -sprites-like option
  • When extracting the Doom alpha 0.2 iwad, "Can't find PNAMES in wad".
  • Doom alpha 0.4 and 0.5: MENUMAP is not supported.
  • DeuTex should not look for doom.wad in the directory set by -heretic !
  • Heretic: E2END is extracted with the wrong palette.
  • Hexen: does not extract graphics quite correctly (applies transparent colour translation to opaque images such as FINALE1 and FINALE2). This is probably related to [1].
  • Strife: compile scripts.
  • Strife: what else is missing ?
  • ROTT: add -rott and remove the ROTT macro.
  • ROTT: use AP_PAL instead of PAL for the Apogee thing.
  • ROTT: work on the identification (ANIMSTRT, EXITSTRT, EXITSTOP, ABVWSTART, ABVMSTRT, HMSKSTRT, GUNSTART, ELEVSTRT/ELEVSTOP, DOORSTRT/DOORSTOP, SIDESTRT/SIDESTOP, MASKSTRT/MASKSTOP, UPDNSTRT/UPDNSTOP, SKYSTART/SKYSTOP, SKYSTART/SKYSTOP, ORDRSTRT/ORDRSTOP, ORDRSTRT/ORDRSTOP, SPECMAPS, PLAYMAPS SHAPSTRT/SHAPSTOP, DIGISTRT/DIGISTOP, SONGSTRT, PCSTRT/PCSTOP, ADSTRT/ADSTOP).
  • ROTT: seems to implement lump aliases by pointing to the same offset as an other lump. All lumps but the last have a zero size.

Graphics

  • The presence of the GIF routines might push DeuTex into the non-free section of Debian. Would it be sufficient to #ifdef them out ?
  • Determine why converting Doom graphics to PPM and back does not yield the same thing. This also happens with BMP but much less so.

    Update 2000-01-04 : for example, with Heretic, patch WALL17 has its (4Eh, 50h, 4Dh) pixels turned into (4Eh, 4Eh, 4Eh). It seems DeuTex sometimes uses a close match even when an exact match exists.

    PPM and GIF do not agree with each other. An extract/build round trip on the Ultimate Doom iwad does not produce the same wad on DOS as it does on Unix because the default format on DOS is GIF. If you extract with -ppm on DOS, you do get the same wad you do on Unix.

  • Bug: some flats seem to be extracted with certain pixels set to the transparent colour (Doom's CEIL4_1). DeuTex 3.6 for DOS exhibits the same problem [1].
  • Building seems to be slower than extracting. Perhaps RAWtoPIC() could use some optimization.
  • Include the Gimp and PSP palettes in the distribution.
  • For people who have old graphics files generated by DeuTex 3 with cyan (0, 255, 255) as the transparent colour : it would be nice if DeuTex 4 could import those files automatically. The way I see it, if no transparent pixel has been found in an image so far and if a cyan pixel is found, a warning is emitted ("Warning: xxxxxxxx.xxx: assuming the transparent colour is cyan.") and the transparent colour for this image is set to cyan. This would make for a smooth transition from DeuTex 3 to DeuTex 4. There should be a command-line switch to disable that feature.
  • Sneas are supported when doing -xtract but not when doing -build (they're ignored). Fix that, or at least mention it somewhere. Though I don't see many people wanting to make wads for Doom alpha anyway...

Sound

  • Regarding audio support, Matthew W. Miller <mattm=infinet+com> offered the following comment on 1999-07-04 :

    Audio handling in deutex (I'm referring to the irix 5.3 version's included source code) is, I believe, based on dmgraph, but is pretty dire in any case.

    [...]

    Also, one would hope that eventually one or more of the source ports will start to support bitrates other than 8 bit, and (maybe?) stereo samples. You may want to start leaning on various source ports' programmers to get their acts together and start coming to some sort of agreement. ;)

    Importation of .wav files is pretty crufty. Like dmgraph before it, the deutex 5.3 source expects there to be just one big 'data' chunk, and doesn't notice the 'info' chunks that certain stupid Windows programs (*cough*cough*CoolEdit*GoldWave*cough*) insist on putting in (usually with copyright messages for the program itself, which in a just world would be illegal). Greater explanation of all this whacky chunk business can be found at: http://www.compsoc.man.ac.uk/~maniac/resource_web/wav_file_format/ (wav1.htm, wav2.htm, wav3.htm, 4.htm, 5.htm)

    Essentially, you want to clip out the first 'data' chunk and ignore crap like 'info', 'inam', 'list', or whatever.

  • Fix this :
    atc4:/doom/dev/test/wav/16$ deutex -doom /doom/doom -xtract ../16bit44k.wad 
    DeuTex 4.0.3
    Main directory: /doom/doom.
    Extracting entries from WAD ../16bit44k.wad
    Reading WAD /doom/doom/doom.wad:        (2306 entries)
    Reading WAD ../16bit44k.wad:    (1 entries)
    PWAD entry identification...done
    Color palette is Doom
    Warning: ** Appending to file ./wadinfo.txt **
    Extracting Levels...
    Extracting Lumps...
    Extracting Sounds...
    
    Bug: *** not a WAVE ***
    Please report that bug.
  • Look into importing sounds as .wav's. What are the highest supported sample rates and resolution ? Seems to depend on the engine.

Command line

  • The command line interface is not always intuitive and it's fussy about the position of certain options. -iwad seems to be ineffective if placed last. -xtract and friends must be placed last if they don't have all their arguments.
  • Options shouldn't care whether there is space between them and their argument. Hmm... or should they ?
  • -check shouldn't require an argument. It should use the iwad by default.
  • -main should be implemented for DeuTex as well.
  • Matthew Miller wants to be able to specify the name of the iwad instead of just its path (this is how it should have been done from the start, IMHO). Possible ways to do that :
    • stat() the argument to -doom, -heretic, etc. If it's a file and not a directory, use that.
    • Look for a different basename in the iwad directory, depending on the option through which the directory was specified. E.G. if it was set with -doom2, look for doom2.wad first. And if doom2.wad was not found, emit a warning. -doom and -heretic should look for all basenames because that's what previous versions of DeuTex did.
    • Add an option to specify the name of the iwad file, without specifying which iwad it is and let DeuTex guess what needs to be guessed. Apparently, there's already such an option (-main) but it's for DeuSF only. Why ?
  • Add -V (equivalent to --version). Include the URL of the original distribution archive ?

Documentation

  • It's in shambles.
  • Mention that negative patch Y-offsets are forced to 0 by the engine.
  • Mention that sneaps are extracted but not built.
  • Man page: mention that some options are DeuTex-only, not DeuSF.
  • Document the messages. What I have in mind :
    $(msg AB34 w
      "Sneeze %{name}s: %{num}f dB > 100 dB, bad for straw huts"
      $("fname (pathname)" "strerror (errno)")
      $<Sneeze $p name is louder than 100 dB.
      Versions of House lesser than Wood will collapse.$>
    )
    which expands to :
    Warning("Sneeze %s: %f dB > 100 dB, bad for straw huts",
      fname (pathname), strerror (errno));
    and :
    .TP
    \fBAB34 Sneeze \fIname\fB: \fInum\fB dB > 100 dB, bad for straw huts\fR
    Sneeze \fIname\fP is louder than 100 dB.
    Versions of House lesser than Wood will collapse.

Platform

  • Borland C: to revive the port, must find a way to make all pointers implicitly huge.

Misc.

  • TBD: New options -fstart and -fend to control the start-of-flats and end-of-flats markers used in pwads. Default to FF_START and F_END respectively. Warning: here again, don't use those options just because they're here. The default markers are perfectly fine, and they conform to the de-facto standard. If you deviate from them, you're asking for trouble.
  • -f_end
  • Why does "deutex -ipf alpha -doom .. -sprites -graphics -patches -xtract" trigger "Error: *** Can't open file ./lumps/titlepic.lmp ***" ?
  • todo.html grows faster than changes.html. Fix that. ;-)
  • -usedidx: don't count sneats (-nosneats ?).
  • The dependencies on deutex.h are missing in the makefile.
  • Integrate AJA's patch compression patch.
  • Change text file line numbers from shorts to longs.
  • If you -xtract doom.wad twice then build, you get either a PA90 bug or a wad that's twice as big as the original.
  • PrintInit() is called way too late. All error messages relative to parsing the command line will be written to standard error, not the specified file (asFile). Options that set asFile should be honour in the first pass.
  • The fact that Info(), Detail() and Phase() write to standard output is wrong if you take the stance that the real distinction between stdout and stderr is not information vs. error but "data to be processed by the next filter in the pipe" vs. "messages to be read by a human".

    If so, need to check that all uses of Output() are indeed "pipeable". Also, is it right to copy Output() to the log ?

deutex-4.4.902/docsrc/transpblue.png0000644000324500032450000004310507035074523016742 0ustar aymaym00000000000000‰PNG  IHDR@§WxugAMA† 1è–_PLTE  LLLÿÿÿ 08 $, P<,H4$@,ÿ··÷««ó££ë——ç߇‡Û||ÓttËllÇdd¿\\»XX³PP¯HH§@@£<<›44—00,,‹$$ƒ €xtlh `\TPHDÿëßÿãÓÿÛÇÿÓ»ÿϳÿǧÿ¿›ÿ»“ÿ³ƒ÷«|ï£tç›lß“d׋\σTË€P¿|L³tH«pD£l@›d<`8‡X4€T0xP,lH(`D$T@ L8@04,,$ïïïçççßßßÛÛÛÓÓÓËËËÇÇÇ¿¿¿···³³³«««§§§ŸŸŸ———“““‹‹‹ƒƒƒ€€€xxxppplllddd\\\XXXPPPHHHDDD<<<888000((($$$xÿppïhhß``ÏX\¿PT¯HLŸ@D“8@ƒ08t,0d$(T D4$ ¿§·Ÿ‡¯—€§xŸ‡p›€l“|d‹t\ƒlX|dPx`LpXDhT@`L8XD4T@0ŸƒdxTƒlLx`@hT4\H,P<$D4|€dptXhlP\dHTXlä»R:tÎð‹užœ1m…µîȉž]O™©íÎ5¶ó:Ÿ4hWW寣GÓöþM¯=nfÕ¯gQ¦ ‰ $¿®‘NÃZ-Jm„™{¸9õÀ|­4«^³KGŸÑ|úÀËÖЦ/»VsÍ £QÅQtÇxî~ô ’þ>ní ½*³ªwýn›:µð}ŸÉçÌnº¹Žäή?[¼0üðñІù)£ëøÉ´qÌ:)ì©§Ièñ_ø(@çë*Ê:ˆ¢Ò¡-Êf7HÂõÇëþ‚n±ú×D Vðyÿ–' κ…¹B]Ä\ÏÕôÏæcxP'RÛ=Cªô׈Fok¯m ¢!II$Z^ù®\§¦ºnÅ/^T¸äVP¯•AmÎ,¹ÔÖL¥Ù3¾˜¦Ý:gºÞHtEnMk¹|¼§]½Êâ5Íbg7é•¶› Ò¬o í?ßÚôknnçfêí}k…}Ûá{ôŸ¿ö$³U;ºš:…觇/=WÖjß,Õ ¿þœj¢óé+Ä,ê”(TÓU¬¤‰ò'ïb@VMW{›:w eb½¤·1ã,FŽ+*%[G$Úse]“Lñ¤F8ZfÍÇÖÙ‡Ž÷HÎRÃT÷Ý['ÐnåpÍÖ?vÇwÍäÛʃ^ð,Qp¼~r=ü¿=Ý,[{g|jrZIéù·ÖT%¦OÎÐõ†ýV’“uÁÑz]㤢ì„òË•íħQ­†eÁÊ„!»Þ-F÷ zË> Rêå¬ÍªX¬¶ã¦Hf¨kÐܵZyÖå:I;·*Ô—„Îûlm¸úé,Oº—Ôš™ÙZ¹˜­ž~vƒmê†H³$ꨒ¿1éËÁªÌVÅ w~H |Î0²Dô'³N*غŠuW?h•Ö5K5?e³Æô%Ž`ׂއQÆ®•ÙlزªQjg³žbJBÌ †åvUŸø Þ=’Z§5ÂÙwOIÓ¦kBåU„ëÞ;  ¨4Í$2?I®6}®½u³6˜ˆÒ3°›Þ¢•=œÑ¯Ej:ëô+©Ç w¥YR\›%ébØ¥õÂRüŽKà­--àשqš…ý×ò[ãÚü µ·®—“¿3ƤÙFˆägÁÜ`\Ó´ª~·[/f·¿[æ; g¬z¬¿Vî_'ÎìÜž5íOS•kq'ç‰ôhKö—;ßQ*Í¿û^3ÀТú÷ÚBöѽ¾ëŠ7m«ú3ØÐî6¼{íR«ÃñoàÝÝ${ùŸÔ £mX½³*«M¼é‘Ú»\ð»Àðïðg€C’ð¶G 1M¼¤ŸraC·µ°=®ï_ûSäÃñŸ¿µò%Á[zš‰¬^ÇÚ<òÆSÿA¶†o5ko÷ÛÞí@*¼Ÿ ĽšH`W¡ÞÅÐùŸ†±£ªÁmô¶gLýIýwú'€2PLð½kYk©ýЕßlýÞžáúûèßùNûõõîMLîrV›·+¿Vª~?õ]w4síƒé]Ò±Š³ÙzëôH?3ãëÜ4æm‰¿…Rø? Áä€> ѵQ®'üaà͆Ì2/CX˜ãýœþ×ýäȯÑÑxo‡Z× dýïGï†’× þdUHýï;´ÎgU›œ6ü$„ÄóÚ0|EcVè×iÜÍí½ÞHùëlÛšèmÏÿ^Î'=ä8t*`4fd(Qé±½b"H'Ý`á]w¯•¿óë¶Ú7+Göï¶­üéÀ±ÈúÁÂè §»¡]Y.XgÓ=ô–A—iﺦ}ëi=íul¤Õcù™X¡·¾æë[yÝ¡¤&²¦E«4ߺM7¡89‘FÊVÏHé#ÈìgT|a¡¤Ãô~’Ȭ43Þˆ~õ\äD?œÓ¶Xäë#Îû§µhà~˜áu>Êd—z*£‹¦3?Åß᣹çNÜý¢X_'Ú7(ézÅîÉεò✛ϫ:_ältÞQÓnÚz†Ä¼íašÌÈž<Øh_z™ ܦ¡œëfðÅ:{Ë·æ. …áak*(Æ:¿á(?Uõàº- òVÇqçt<CÀßÔ •¥-—®gsÌ•¼ùnË®¹îVq‰m®™Í*ÜÇ¢("ÃŽ9~K¡_Ù'¹ïz2ö¸z6£EÈã3ˆQ×ûÐ`}d,mKëlÓ”.½ô·v}Ãwü2<ÒÛ†ùéOŒ/=ábÑ=DóÓÄîìЪtfs®‘7a0Ièª×(ÉCÍhd¼-K·„2å%!lÊòÚ»Ü ŠA3@oðOçó|>7$xnL¤mROJØG!’7oavÓô¦ë·‚Ëá‹ 8p·©GGW$(§¦×#(ˆ-!¤Mκ†Þ,]YY[úw’€Ö{¯ÿ+’/âÇVvÌÛdÂß6ãÈ.’.³¾µøëÕ$Îú§¹šÖþCçYȼQ#iœóí5d|XèÄ{” ÐÚ†þ;[:’CK(>r?…ÞÝÌsI¨au­ð&ºáLÌNn¼ËMÁbøö÷®'ùõPTE·é¼O'$ 79è½ TІ¢/²ÝØ©òRÇ*LIKúaÀÒµ5å2ĉ×à»Öî1 ?ø%ÚK×PŒèo{‡‹Ç7oã47Il½4e5{a¨+.n.Ãcîz dD ùÚ9ŒÜ."÷¥s%‘Ì@¼%õv|qU§Y‰ô_ ›³œ;¨ÈRøår9@W`Å+FçÊ0—á`EîÌbÔ—Ã4[ºF_¯ÓõUÈ=€žTÌq›æÒ™Ñ4Ve<÷"0@ !X=µTØ7Ðc˜@¸ò–ô°ÉquhšmS,ӦϱR/vf,§ؼžÐé˜ÜÒ-Ï— ÀŠò="{€ü’¢H–…ËMº%gkZC6¸ù¦ó‡íŠøª“1Ê>™ç¸YÊrá>QXKE&økÎáEC͇Ax!=¼]½\[Ã: 7ƒKƒÎ/Ïíi”)¤—ÉãHo‚³±·¹Ê-—°¬© @Qa~Ijàä µ‡Ü2½&­h§Wœ錫nìAI†!w( @•G.ªÎyß$=C NåVVp*Hõ`¢ôåÉ6"9Ñôø Gº¶åIuR-Ï—|t Q\ «-®{6­ád§ä0ž%~ ¼í¨p¥Ú çÕª $yô s*š]4)Ó𙈑Ó_]°£B&ã«0š`6¡è5ª™Æš¥(ƒ"°#ÿ›»¹c€ ÚO‡ñÐeÈ}y˜ÂFžV'Dq¹¬ ·ÁŒ4ìoÉ‚¢7›\àååådIà*Èüè…¨0 Zkà€Ù­@Ðå°áÈÄk6©zŠjºPlæZ=ï)8I 3qÈšZ8DaZ‡±Æ*âЕÄOÞÌI{¡Â—#²iXé¼x¶îÕ±=¥àÇ׈ á¸É‰ÃêᦙÚÖ w v——·nݺd€UÉ鯨°€9ÌYó"‡/åœ(;Ž<_L“TßzVNØ6Í­[‰ˆùˆ²/sÍŠ~gŒîv'¡µõ@?og™IS³lÊýÇOn6Þ“õ÷°}¹h6A¼`†¢-—8©¥'Á"‚a_àŽÔô†4·¤øøòÒ?K'c–ÀR%Ð1À‰ÐC¨60„ À²,ŠQA6.©àLo´¢z…éÔÓ•÷V»k·I-ušï¥¾ˆTØ ÔÅ6qžžd(¾&‚lÆÐ|ì…aûp)žÝKÎ]PîÜÕÄlIß–µg$ $w‹,{RV儬Ù%ìñc€d»%$|NÂz0@—¤—HPH 7*Ä@°¦.+ ç M_WOM,élâ®ÅXP ó¤¹8AJ½hð4 «¥_ä,r Cœ³Ò[ú*,òÖ(@qŒ´ÿÂ/)&t ŽEpè,èϨʲrÛx¹„ €°•×0†JÈÆO¼p N‡DÙDDNi(I‰rè;’§£c¿Nd`ÒˆG3Œø—êzĨ…zàTçr³Ï˜r%AÊ„ìG¦|(Æj4²ËYSá6,^{H›¨0 dmYVI )l´§§O,Ewç´‘½\ÎÆX8`J:$&²T€MHi;a§#@—¤o(º„äПrMdÂüLG³;ZžÄ5¦gGaçžÉ c­6õˆÿ$–9æ~Nâ‡ðƒ%œ,³¡Ì„b_H+NÞØÃôáJ¬Ä‡tœSKàªåyõž­ìeYNà`ËJ¢mÉpU-íÒK§¡Î®‚š [”´‹·£œ!”+/Míéo³²_²ïª/ÎÄ.Èœœ´(Y‚Ö½¼añóž­=ØA¦HïH…mÞ¨æ6¢Ì^B\ΓskÏ)–Yž-—çŒÇNØÀ‘¬Ü*@Gé,9*·UÜDþR€y(NX£BäØrt°‡dq }Olš5üzé“oÖð”‚*÷Ù õ@Õ¹iô'ÊYrÉ7”¢ ¢ÇƱ5lé“Ü‹6#Ú9ߦlví !½ôJb„È-ÀK[ @r*K–ÍR%ÐFý ] 3]€ªËRbs 9¸¡f³Ð:jPÆ"诚>yQD@fíVÈ7T‘ s=PFRK=PÒH-g-jWEq jP¼àF¹œC)ʃ+FŒ!º½M˜ô·>ŽUI¸ ‚“Ž¢«XY()Ž­ÄaC_eh@ö¨™‰ÆÖ9;økôŒd+´ ^\ʯŸ7ý4ºY!‚ê\cF˜<¹Äð9‘ëK9¦ñ'Û¹š¶"&šÌWÁi^HD…Ý6 ‘]nC-«s²m¾„´Ñ·I°W‚>ÙehE…‰«AHÛ(ç+4Œgo#lÚµ`ˆݸG)¿Vj!Ó+˜kÓFÓ1•k“lí)˜‹’L-ááTv”¿v/*@ÍDôs©§8IÑX«9¹Ë0ƒàAÏ)ñNÚK•H á+-w ÃRæ.„9—Ò:Ïãë¼Ȇ•™t¹!b—_T·VU"½Ê`p‘åòwsâj>²8#.7ŽK ·l ›¨Â^no©~–p΃-lø…Ä„è‘{bçt4NˆíéX Ð*@2~XråÂÚhÃђ潬Þ*Š*z⤮lªÂÖb&i¹‡?½Ä]a€â…*'­„.} „‹ïXZA¸"+vw³ÐD–QGðÉ‘U±ÖC4`(¨vꚇz––³PÈ «„¬¡˜€˜¦á·…&®v”Œ¢õÂC?B®Ñ(@ú!k\…Â#÷ðõæ‰ »Ü‰ ëW!™ý'~»…œÎe¦ðV>ô»×8ãþo¸ jt€å^¬†ámºb-Ep®"Ëð¢¯y®ÅI;rœ'"ˆ‡f‰Îxà«z¹ôð¥Ú@Ë™ˆ1®Æ ëoR¹.ÀÐÏkø(&Gp­a~LqÅ"’aÜi”8Ó’‘ÚÀõÀŠU8)¨&õ@#ÃÛÄ죜åypQ£Ã.äK#4u(*,Ù±¨° µe¼ô)@K3ço¥›@îû€PW)ÀÔ —+ÀÔA( úÉØvа6ç#³±¡:Ì='¨ÿ\°¹×ðÇB=ÓJ5¯ÇšÖM“tÌÍýœCk"{!ˆ”D‹ b礿"´ƒÖSéE­\ €´@2e etˆ¬~ {m+îU¿ÐD€ÌÎhŒR¨­3b`ÃÜŠlc#Õaäu’"÷±¬F6سXYq| °LêÚ;Åo` Cg¤p„e.`®Å„`¨5掑cÃ…| ¤ëšAÔËFŠMŽÒA l ’@–¨}ó•d û Ј Œ~Õ°åÓÌ„ä C=òl‡îÂy Þ,4F„ÿàÿý°HÉ›¢ö~Íâ4(g…–³¶HÀ$¤Øšþ™PÎâðc½ç\÷“KhBBàDµ lU×sî©-FoA½ob¯;b˨üÊF¢³ÙWHÌmˆZœH\¨n "ÒN(© P™J ¢ ‰X%ãÙxY¨}^5a6ïìœí„í«g;dõ2 [X}RÄà, ¬¥#|¾qAƒ1èKâ.ÒË ,gçø˜¿µáûdé¹COy€aç„ÒçRÀb€Z\áPùUt\Wb° "­V€«^8†}FÌŸžj]*@ØÃ(:\ì"@ LV%$‰²e]¿¤¯úóí“ÓÓóí“GÇÇß~ûí³ÓÉtÿìä[ݾúêéÎγ§¶d\#–²²‚Œ$ZZËâr–×2FëÖg§¸,ƒÁ£ #…X’ÉÒÎ&Œ+bÛ¸àî_ÇÁ^F°àå’Ï÷°VÆ ÁBNY‹›%Ò7î¿othôZ€Ü-Ï©Š»-žÁ;(@/öùmïh¯ 1Áí7&ç¹óշߟ9!€çôþdçø„žœìîœða7ö6èÿ>«p[P•z`ç6â00šƒtµd$XËrŒ®G®–€:Å·z0L8l´–bŒ¹¸05†À{4õÞZ ”Fí)k.2«¿[f£¬âî^‡ Ć@š W€ÅðöN¥– ¡ÇšP¬½¸@Ü£ €…Ú@öÂ5S!bÏH ®®HgJò"—åd2&H¾äädçd<™‘ˆîì'Bn„¼ðl?TÛz —z`ož)6xq1mPò´ ÃÖFÂ&ÃÃéNñkv®®NéàOÜE±v»`ãÒAm±Óf"’G€ 3ÍvUƒi¯½½B2kr"Çgûõx‡œí‹'ŸŒOOɉó8%—òí£/^²“I½qv¼óìøx‡É3ÚÈ  ñb!dLê3vÊY2²qÎ!.£­ÆtåwqAv‚ Zϣ܅Õ0CcH…kÏý€!–tÍI®†ƒì(À‚»Aƒ)!!€œnóP¤ˆlÔãã‚s<Þ¾„?<¿º:ÇÏËmr"'Ç;ǧg“zÿìlc÷ô„üïÞ›‡ Äži'=Æ:>Ðûd pv$0„à'hß>è8§o÷¹—DßÌP–¦×‚­Â iÄ$ƒÍ:€?®ßÄTÛ´˜S9$¿dë\Hv3uw=ª‹Ý]Õ`<º|J†GÅíâ¶H OëÉÞéîÙ9àmLª ¼ÄÜŠm<;Û=%ÿR“ ïmœ>¸X#àë½QÅ\lÚámu}ËËÐs"Ä3•Z~žC²Fß¡ò~7ñº4Øq*W;ö"ðÇ·Ú~MjÔ û=€IS€PZ—goŠ Qá‡ÐÿÓ=x–ÄPà‰Üß8;c€»ôo ™çƒõÀ8¼ J|ë—³ü>É×%xå7ÆTôw?·Ë&¼™+¿ÆÈ6 æàœæÂ¨h~`–ôE/ðú ú¸¼õcí9×Á½ì2¢îhǃJ`ž€ì„UèGgpŸ‚=ÚàeÈqàÙ†Jàx÷ !6h¸ž*²Ö«ÖqïýW ËÞ ‰üdÀj?.ÜùCº&¯+îvâ\è|Ô0À7¼opüƒ¾½ycÌÄϰýðc  £8Ò ¾„¤ÆQw8wÙ.ôˆ^2Ô0ñÀ=ŠŽ½ÀqIË’–ã ‡îàÆžüÛG*'³¤Òz ŸÞܰ#¢—*¨ïE×›Œá2ª&þ*üfµzŽôŠp.L ‘{Í[Á’÷šþáÿ¯y €ø¶7?J í\Ýq"’ÊåRL0p]ÈÎŒ ®€È>ò` ͆[€ä$Æ{q I ý—rÍ[8@lšÎKL-«×òóU4qs½òà?&Mn]û†ò •?×Èôv%2¨Å3@bõ=¶âûï ý €ôõ½1ß ý”ßÿjÍÃØ’n.,Õ=¤o†l«!wL PÝe€†ÅͨPÈ#À½³}8ÀqH¿ÙX¸§{UP5sFFgq~ƒîÌ(sØÞNx‚¾c‹ù5,7\rÑ ol~‚-@8ïE¿ÿAœÈÛÌ5i¡sI„wf<À·È gÏÁ¶?ÖaÀ=•À1ý»%NdŸu˜TX†‚ª °œÕ~.Ã3Ó!¯ ÆÀæÁ}ìsRĉ Mp&c~£Q]2n•¡š<ÓrJ¾Æ}¹ òû]od‚ëÄ€Þ‚…® ÈH Aì’E€m*<"÷:¡6Á¿i‰TnB™pÉ?ËÉX÷Æëg“1 ëXîA…)ÿË„Ÿ °äÌ<ok·[\Î2MˇhµÞuJSÛ× ‡é5ÛÛçÛË¥ _n/Ù<‚)Àïuûáuòöuà÷»Á\ØqÌ£…òЧi €RHeÜÝ$lÂpÁB¤°•…X5j¸Þ„ñ‰®‰z6™pÞ\‡ç˜pAÕ¤®u †0¼MÖ§Éø­lʵÎ(Ž(PQÜBCT¡U—¡s³½½ÜÆðèå9–`ñûŒÝš…ôÃŒtDÐJ]†R’XUE :ÊTùì,MüK’¼+®Å`BâŒd’ˆ1M:a²‘!¾ó< °dÛǯÛámºôŽž‹:ŠÑÒ!üóŽ ïK.5èØ£‰X ×ÎÏ+‚wþ#¤ñ‚^^Á ‡È¨zN IDATƒÅ›€-¿ßaýŽÁ\˜…)×â=Ñ!€3íŒÛÕºþ(µ˜Z®BHÿö`æØþžž=þüqI ¶ éïùX’±±.Ûp¦ÆÎ‡Eñ³¦3À’#šZ¦»ÊjsŒ‘à A•¿\‡ôz•?™3 ÚÐä¨ÓÈ8Ûå¹=ß>?…ü‘Ž—öü¢Õaø†âš7_G| À^.¬¥›œ²%€E´€»»üëBa`>ŠiD¥Îb ˆ¢ÿ/'W—v"dú&øÆÁ}ÉD„  °„ß­1ÈâŠi^“A_1bä|Ž1Ò<¡fkèy¼>ñšÊàh™)ÂýŘ\°<©N·—'çàY)•` ð‡…à€ÜQŸw¼°–±àP¥§HŠÒè*äÊþn8±æ2$!”ô‹¸Ì¦“ €–ÈdB²9¥üx*÷Ø_#ŠÙG5&3ÖÃK ¯lÚ§÷h.Wó4âÆk°c JMÉfÖ͹ªÚäÜ1Gß< ‡¤ÌnýêÓ]OOÀo'`ñ:,~|C?ÞüXt¦ü~¥¯Ÿ ë Š„fÁ!̲QôPÖLJ2¼ä£˜ÌIÙ½”3hãKàÙ>z&¦S iöÆ“7.¨6ºþ"÷,…‰^<¼­Ž£³0€†gG;â]Jß0ÃòܯÓäÚØ/g°«/Ó™¬[Û‹ùÂËó㓪Zž”öô"€¨&¼&€¯»_wøµ{¹pÈ6pQèÀ ú@Ð1,)É@ƒGIIŸi,Ù›`öOi“BØ`é{I¿Ÿ Ô™ñ×”K ¨ÆÔj–¸à§éè,/ƒ‹à«}ÉÖ˜€gEgó&× —#?ž§©âQ ùµÓå鲆zRaç."AÈe’Gø£ùñû7ðµ1€!ńЭ©*ŒL„¾1EF, ç¬C4XÄëY/O^½zù_/wž=}º³‹žàóÓÓ“íí²¤º,/¯0%À X¢úßYT ªé&lkYs"N×ä¹rFFV:™*Ç£Šš0Í¡s ™øÌ·šîu½¤l¸Æ´Wçæ—~á²|LêròèÑ‹GÇÇè C…O÷÷'plþÄ9hAµ&‘Ü“qB…eº«Öhê}–?‰ldJH‘7µ•êe Å¯G‘`rTcÞGm—5ÏöÜíÞ,"@‡ï?š7`_ K`èÕ„¾2;‰¦9Ÿ+¢f…-¤gX<íøå—ûÍÑáÁ7_Cæ³½¦ÀÔoô —åçÛã³ÓбþôÛ“Ét#Ž_¼øê«§O¿újgc¥ *ƒ•>9õì¿0Ž!€<áºýHñ£H â×J`˜Vhœš8ð™;#¨*¬NšGX‚QY/¿;…É Y¼G*œlíj*9:ÕI}wÈ·†¡:ŸX‡%õ@ÞÖÖ´d®œ°~Õu,s¢=üf €úì¨z“~CŸ@Ï…,„ÒbŒ×EWQ ä~aú÷âgxq±„£r/Þ—‡ Ñtj I}I½ôfŠ|öòå¸$r[¦¸}ûö{ïÑÓÄiŠaÒlÞ|›¼ãMG¨ÊKžéÔ$ÃÛ¦:*Ù²®Qƒy^Å žšÖ5ÜÜ$é¬7kÛøÍÙ&íK'KtCŸ,!€˜¨°*1—£udBÂo`n„VªúE˜Ïãys¨‹¢ û`ˆ# Aƒ¥œO?n?ýî»ãS²€pAð2¢X4qŠb؆é‹é ½ø›,¨i`Ôz`ÞÆÎ8æ(^—@ÙÜdÎàf &} tôèf¯ˆ2^RìRó|ámBAÌTZøº@Lù°t&™A€.˜ÀÇäZÑ*ØõæÛyúôÅ1¥Â’Òmn-(Ž ³Žãš ­Ë¦™éøJ`|­O‡·q9šˆòêš”2ÎÉÎ 3wBŽáÍé²ÔͽDºH 7¼jà’ Z†ù«e!ü1å×·MÈÝ‚« Ë ç|‘søRÄ#Ø=ÓÊØr@ŽÇcR^:bŒ‹bHÖtòw!ؼíJ‘K2c½]Qëíð¶ZåçÊ5¼t‚󺤪—uCç)1}(ó $¬¼$¡ Ó`ºk­Ó]·‡UøBW2Á.¿A€&(ÓT®ÄÕF€0{HÈ¢®{RŒürÄqáÓïNŽO)3Ý8°‡/Ì[“¥ìŠ‹‘%@u~(×å"µ×Hz.Õè† 3¨~pÙ<)&ÈRtNÊü*ìØø5 o¶Â4%,"¶V…/’—~}žä¹q¹Ä)Ú©´³Ç†Gï—k™â@WãÀŽ +Æ®u®oy Pž±Þ©bº«OBt£ü €MåÄÄ5f§ÀG€ü˜+°c ïe9¦9`¾0Os¸XK°¸`¾¢ÂšÊI×p—[Î R°I.’:ÏGº” Û¿~“Æ.É»†´¶aŒ7:c]¶X4í"À²Š§|sœ9/-=ëâŠ<~ÎëÅC<½‚2@Ò_¢X[¢Taé6g‡2Áâz€Î¨Ý“RLPaZ.CôuCáe1)¶£:ôy­HŸœ¬ÄÆ¥9p1]%©]µ•½pntÆú~[äé®>¬ l¤S:†Ä¦JWÞ\¢3ϱ\ˆ 7ð#X¸Ècœ/i12¦Í]¬A¥±`£=`¹&¹v+q*‡¥±´Ó+€zí™Cô2¯}Û×kèÜ—/Ž¿%€i³(œë¦¾]¬…çy»”†‚ªN¸Öz ¦»Î¥¯Ø œÕ]éœ%Îò[–À†ÎEA|3TØ‹ s ÍÓ(¦k¨xysÌA)&\ܰ]í)TcŒŒTÓ%Ú˜ë(vmæùÒÕuX:+ ŽðòÙñ‹§ˆb’0¦0ŽS¥h몰kIæZPõÓN=0,! Z#pIß;Ò0ª_Ø4G(ÇøºrÛŠ+þÜ£#î]—àŵ]X ¿-Ä誳<°}$®„ÁU\tÇ€âÙ“óêÉ鹋—þôÅÑÞ6ŒÉ[RÅuq½8×®#%Õžáêã„ë&NwåHš¾Ï1Ѓg6sUá†UØ‹ 4üè€g³ 4 <ÜâèùáÑáüˆ¢EžîêÄŽ«Ô§Zä­ üõ¬ŸÊ%µG„sáQá-G+’Àѧ¼ <ò¨NæÈ’¤©ÄÎñw’ s·’)à{&w=Î㪣¶bZ‡l3((®Ãø@žîêkß™ñ*A~Ê» a@ä'¬Ë¼H@€Gôû#¢wDÿñêàðkè´Í†—íÐÇ1ðLô× Á¾o™e+Mr¦ˆ"–‘…@rÔÎëe.±$é‹K„â‹Làéw§ãñlSêúïQ6RtÁÔô£#ŠIiPR9YÔ4ñ¼~VZÌÂCEØbÕ¤"ð¹WnAIç‡Ï9A™qfrtÄŸ„’YÒ§‡Ø¬©Œ¬]‚‚™3YW¹Ïoë¼ • dO2ØÈ¨˜åù6¬eDqE‚¸LVo KdämÂý ÌxËÅMM`ÆäíLQq"p¤Ê¯¦»êBúSYý¤‘eç}Åç" l |*¢t´`9<âOßa:‡zÖ o¸<%ƒ†Ûaרn³{§hH¡>¾€Wo”cðÍ·÷ŸþêéVѼ|µeºó¸B YÈ"t·¡ïåt¹ ô¸¬dAa£ë.ämu4.BÝ]\çaè@ØTeÂ5j1ÝV½¬›@ßjYbÁ°+™{¨êsúvp@¸`ó,…xõü›o‰;\d‹9†ð>'Ê<Êfÿ”Ç`(…—u÷uee™wOæo¿ºƒ¸ðÎÖÖ6φ4±Sx¡©H¾(([$Ý&†Ô-­­ââÉ©ê2Z›M¼Èj<8Єë"²ÌbžæýÅ謹ÔYç u6îè9Y6QSlÐ_’Â9Ëž˜@þ_-„%vÏ=€ÆËúòyZ ª·÷½˜¦âgwTkØú_-ßs·RÁë'ÃmlW°ÅÄ™Úè­+daeþÖÓÆq›‰Ææ}‚±"ÍxQPÍM|r“Öõibõ4–³dé"–ÀCRÐç‡ì'”‘¸È\Åá\}ÅóçÏçq7¥Gûq便·÷ìôtÌÓÒx©7èÃåÒËÙí;èîoЬ¸#"HmÑ©!Á‰D€»É“e»·eG~rIO¸V¶¼ÿ»<˜xø 5‡˜¹d+Èe1³ôêŠÍ¯ª·p`V7›ßýê_wöfõÖæ«-èÄ ·Ãzãº;:>°^Ö¼Ô2}Q3$o¡¼ÂÛ°‡°¿ÈWb“®M–@¶zí„kNçj™)¯Ìå¬o¾Fð8 ÅàXå›çÁ do~ðõ7aWNCÄì©b;ŽS<ÏÅåÇOgey%ÏnáõÊâHug¶ffïß~ù/Ï6f³­Í—,‚¼dº V\J1N\d DöA6Pu·'†Òr_™ÛbA2Å)|Ú ˜À rèmb=°Ñª´øØ¹ff€w¨(ñÉ‘úÙCÍ;àF ƒ*_úmúõeejf¼»Sú­ÝÿóÅßmø<Ýb€M ÐèÑtˆ>D)•^D¾ê, ߆y¶SšÊÝ“wÃ,êÚ×ì ªr9m=èQP·P×@ßOHöœ|ðbe²gÏB†ÕÐͳŒ¢¾Ch;läÑQú„^;ðRT˜Ìn .EM_Ù©™íþË—Y6õY#lÂô¸p@â+,Չз«+×}²ƒ»º‚Ò^¹´Ùöä=®ÍUÈ=È\ÑçWW °pì ¾m=pÖÖç1‘…¦>—àD½[µC–Áùá< Qæb Eƒ>r˜ós•ÜWX2À½=¯PŸÉÃ4.¬¢Güüì7ÏIQ³W›[³Æ4aPj 0ö‰  Ižw g‹“Ë {Õ¥°DÌñO¯d 4”$Ød¦lSå«,LÆÁf–䳄G㔢ŠQ8*ŸªÝAÏY‡çGˆ¨ÓÆKc©…×Ìyá/<ßj«Þšú¯~õÏö—˺1[¨O “Åç´*¬± ú‘êjÈÏ^ wÕ¾K^JÈçr@bÆü¿£¯Ò^•)½«î±]&ÏÉ €m|‚åëƒíQš|è"(4)aw S¾FÖ&ûs5†üE8åU{ÿ­< ¢²ùŠW ­QPÇ8¸°º¬ŸVû³Wæ7û÷ÿð˯ö¦M³E:¼¹±UdAcÏf:ÀÒ,õ~±Jº+}‚ƒž7‰âòàU»µc“R.­j¯*s{ù»8øZèùõ×dHÈIû8’ž=ûòoþþ•yöë/~õåßÂgSè€Á ËË X©Ze¼ZQZ¹£ÄCËõYw ¹¢w%ǽRÉ$êÀÑÛ7ðv¨Õ¼9â;ò‡‡&!“SU~þ >ý†–L^ÞsT±…Áè®Ø ǬœŒ7Ç“é¯ù·_üã/ž™zÿ©ÿ‡§³vˆªLs5¡ªPØà0ôŠ{ñÉU[{ÉSË&$¯Tö®Z³¨¿êÿ í”!dãâIH¼Ž’lL´Vuðõ{xáçèÍU&%Ê MT—w5`n¨„×Ë-VÉÖ(eEQf÷WóÅ~63ÝE¥è¥ ãÛĆšjç\"Zñ:óÕô-tôƒ<¦•G햋ȣ؉ ÃŒâøê…%¸Ó@.„w‹z=—‚KëXQ9 v‘þ4,2 ™¸^ÁÕ@dÅ‚7#„ï½GŽë=º³Y#U…\Qì±ßìþêo÷ÿîßþãîü,Ëä½› PSá0FÚDmìÀè|¥3-ÊË@çd§Ô}ç‰^Å-ØÍ(ˆ™ÖP´\Œ^ Å‘º Â'©­è·ÆƒZ;宎ÃCõöñi[NŸ RUaÎmüK÷®(]7èuª¿jfû_ü2ûWÁg(œ¹½å‹ÌlÅQúQ…MxÚzx8‰…ªpz›V §íùl¬kuó9|0iÿ¶=RÎØYû+È=Í“jUL&T¥ÛÔ#àÑ#&Íu6I‚b‚Néœ ° û06Q…yÂñþ¬ØŸùÙ¯™ýèA à-S˜;`ì˜+Ãí“{‡IZ¥mS°öÚk/í#“9Ö‘j¸œXŠ–5‡mû$A( בŠÜ"&em9TÔ7fqscÊØtyâ´•¦‡FØä¶uÛN:7åõf)$Ûïø¹a6©$Ù"Ëöšg¿13µ€ïÑ×Ïnof™úØ9kËD ”R¢Ói{‹(óÜt}`{x´..ì’V¤À%”!)°øU©ùQ+œm pàéà›Îíægv>t÷-ä‡C1@«ãáh1YÁzçéÓ:K¶;ÙKž>àÂíkµ7K­p‰,uãªVxSH©vä²£ôá¶d!6¹W‘Uì( ¾òÿ¦\Q[=Ó«*m•Mkæm ù)ßfJ¦j‹÷hG˱Ràæ‹ß줶•½ Èr+hzUáRÌp™  /ä!C]{fWŠ®­>õÊá B¨(˜çÁÿ(˜þúŸZá£È’Ú½NÜEYEYj…Ж­±”«¶w5Þú‡ea|ñ?ÿá7Ïö)Wq*€›©p¥¤ŠÑÑÑŽà$ sN•Öj»^ÚžîUØ5l—½•ø.¨²„‚‡ÌÀDcV–Ý#w·²ý)ûj=Èv›Üê—ëYnë6þY=-þǯD7w‚¾Ê¶"@ëìŠF­ÀkÌuÐãDå#©6´ìúò2¨Ñ,èõV¯ËÉÅÑü(l‡©G8ª.Ix’êFüKimw74¨ì>^˜¶‡Ö$£ÿõ¹âægÊïÎÖf–²n¼í J*j}ëÕÙ)îuAÏΈùQ©F§Þ¸§b. ÍR"ÐñX‹áŸí u¢n¨µ6!Té@úBºö‡ù=xø¸ÙûǽY±·³ \,ˆÞâ×(@…Ø%ÇîEgv@ÇUâÕm‹ˆb­§Éà½îºà4Z#€è¤<àÌL‚v¿V°è¶¡ŠX@¦,«nƒÚ¨9”äÉÊaÃ"ëm[KùeYE‰¬>øäÁãÊøY=ªž}µ{rº´ÑC9ÆdÆYjÂI“W¦â^õ~ó§e{AÒi˜\@Åâ,ü÷}'”¤ ™Ä+‡‡š©±æ |jbøRË´e•¶ÓöÛÉ mÛÑmè$¶ÔÒeð•râ÷ÉÝO?Ï ?¥ü|ïËÝÝétVÙ­ŸÒÉ>ëˆF÷¹ärU¥º¨·:}lv®‹$p0.±Ò°bu‹·Ïrb¦É\¨”ö8i¤>J4meø¤me"—UÕ¹DÊNP¹¢…¡~BÛÝ{Ÿ~VdÍþ¬6Yo£êÔÞë­EN‘æjëÜ ßµðØg¾}ñöÓ͕Ц{"ŸLø™ŠIò’:ô]púK~÷ù‘ÂK‚$i¬Dx•Šs5d¯{毊wåF¦Ç› EáÂ&ò¼ úì³O~rŸ¶îÞÿìó¢ðÏ6¾* <>à»í¶Ÿ<~üx{;ÜËö¼á&µ ¯ÝÊ2ê:ßÐp8U7[Æ{‘œJcŠ^&È4wïέÁì6нsC «¤‰©| 5ññ§ïßÁ?`‚Mýô‹fï‹b:ãD.»}Û=yôðá£G?~R%2=›#ÚXV75ýƒ„`Çnº5×ãeíJeÒÙ–NJ}m§yV›Wr«öUÝöUi«·hàã‡?½ÿÉ'÷Ü¿÷Ñ|üðáç…{šÍv))Vñ{üÈ@øðQÕC’´DÛ‰'Æt ›ÄþTjãV[ßBN˜­ª4Š%C”ŽJºµr¿ûQö×zÂnãnn-'&€ÄçÞ'îß¿ûÑûï¿„øCVàѨzòøÞïðáGݽG;>®V¾î©Äæ¬üÂ¥Ñ~É7Š®*Wq#Þ7«. íÐSTÑ]Ï$v›¦º¹’‰ÄðY¬¼]Û¸ðÞýû÷HÆH?ü?yðÙçŸóêɃ{üå_þÕ/€ð>«ljºîKÝŒméJzrÓ[+’úºnÔ ƒªU%@º‚ à®Û.×…½†`·õwøÖ-«HA§2øÑ‡|ðm÷iüäãñ×à•¾ØIDATýWDðý>ºKâ£O«MsBIˆ®:Q¡Þ㛕FýŒæ±ìÇ ýË /²°Ëªþ»¡fU= î¦ Í²eÐ]åf£'¹®]Û>øî½{2üчÝ»'ü>|ÿý>ø¾ÿ~üäɧü¬fCúÁ¦vŠ©Z‡6E‡™ÞOŽU%¬Ö±ë\a•…òªF8Ò¦j]›ª[ÆÇ­Ú`µÓ*»®UŸoöé}ò ÷ï݇’>Ë?üðã?&­þÅ_ýåûwïÝ'Ûh?®ú XI|üoˆY~ûÛßþ9oéõUAš¥­V©™r+ø ÂÎç][T%j¯I•6©Ô&Å6U6}úhûñgŸ> pä…ïÝ%=}øèèÝû˜Þ~|—tú. #ñ{ðèñÈUŸW­ØTýôÔ†§!ˆ§F&[ƒÃBþÎö$Â^õƒ.ªpëé“& ¹×ÕR´9U¨ &.<4ȶ !µ•ÙÇŸ|V}þEÒ™àÝ»÷ï?|ðàî]H#à}|ïúñῇþy42Û-j HÒíOøíoõåoþäO~þóŸÿmøÜ%‘ád³ÏªrëÝhjz!NS•ÆôZ#?£Ó mxuµ®9ÕMÍyüð‰Ýþüñg!L! ß]Îëî~ø>ùÞé Er >ýl{4ʶ«^ g;¹e·ù¿ým¨ÿq›;cSärØú%·Æ]—.ðy3nÁöö$Iwñ“@9-W…‰hë!7E ~™èf0~x˜Éx< [U%{TÁñ…ÛÇŸm@ü”$ò"Ÿ µ÷ñ׿xŸÒ»Oî~ôñÝûnÿórTU'–6ãð¢Ïàþû¿ÿÛÑ·ÊýÅ_üy»ýo?ÿùo±ýçþÇü×ÙêÏþìOÿôOÿøÿèÐf|ýßÿ;nÛíb‹“[²Yœþÿ ¿… ,X.IEND®B`‚deutex-4.4.902/src/0000755000324500032450000000000010305373426013362 5ustar aymaym00000000000000deutex-4.4.902/src/color.h0000644000324500032450000000265507777561674014710 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /*init colors before any operation*/ void COLinit( UInt8 invR, UInt8 invG, UInt8 invB,char *Colors,Int16 Colsz, const char *pathname, const char *lumpname); void COLinitAlt (char *_titlepal_data, Int32 _titlepal_size); void COLfree(void); /*cross reference for picture.c only*/ struct PIXEL{ UInt8 R; UInt8 G; UInt8 B;}; UInt8 COLindex(UInt8 R, UInt8 G, UInt8 B,UInt8 idx); UInt8 COLinvisible(void); struct PIXEL *COLdoomPalet(void); struct PIXEL *COLaltPalet(void); /*end of cross reference for picture.c*/ deutex-4.4.902/src/deutex.h0000644000324500032450000002161510305321353015026 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #define ROTT 0 /* FIXME make it a run-time option */ /*use old GIF encoder, new one is doing errors*/ #define NEWGIFE 0 /*use old GIF decoder, new one is down*/ #define NEWGIFD 0 /************ Important defines ************* #define DeuTex for DOS .EXE Unix Linux OS/2 #define DeuSF for DOS .EXE Unix Linux OS/2 *********************************************/ #include "config.h" #if defined DeuTex #if defined DeuSF /*DeuTex and DeuSF are mutualy exclusive*/ #error You cant compile DeuTex and DeuSF at the same time #else /*compiling DeuTex*/ #define DEUTEXNAME "DeuTex" #define COMMANDNAME "deutex" #endif #else /*compiling DeuSF*/ #if defined DeuSF #define DEUTEXNAME "DeuSF" #define COMMANDNAME "deusf" #else /*one of DeuTex or DeuSF must be defined*/ #error Please define one of DeuTex or DeuSF (with -DDeuTex or -DDeuSF) #endif #endif /* DeuTex version */ extern const char deutex_version[]; /* Try to guess the target OS and set DT_OS accordingly */ #if defined __MSDOS__ /* Borland C and DJGPP define __MSDOS__ */\ || defined MSDOS /* Microsoft C defines MSDOS */ # define DT_OS 'd' #elif defined __OS2__ /* IBM C Set++ and Borland C define __OS2__ ? */\ || defined OS2 /* Microsoft C defines OS2 (I think) */ # define DT_OS 'o' #else /* None of the above. Assume Unix. */ # define DT_OS 'u' #endif /* Try to guess the compiler and set DT_CC accordingly */ #if defined __BORLANDC__ # define DT_CC 'b' /* Borland C */ #elif defined __CYGWIN__ || defined __CYGWIN32__ # define DT_CC 'c' /* GCC/EGCS with Cygwin */ #elif defined __DJGPP__ # define DT_CC 'd' /* DJGPP */ #elif defined __GNUC__ # define DT_CC 'g' /* GCC/EGCS */ #elif defined MSDOS || defined _MSC_VER # define DT_CC 'm' /* Microsoft C */ #elif defined __OS2__ && ! defined __BORLANDC__ # define DT_CC 'i' /* IBM C Set++ */ #else # define DT_CC '?' /* Unknown compiler */ #endif /* For real-mode 16-bit compilers, the huge memory model is required. */ #if DT_OS == 'd' && DT_CC == 'b' # if ! defined __HUGE__ # error Please compile in memory model (-mh) # endif # error Sorry, BC has no way to make pointers huge by default.\ Try compiling with DJGPP instead. #elif DT_OS == 'd' && DT_CC == 'm' # if ! defined M_I86HM # error Please compile in memory model (-AH) # endif #elif DT_OS == 'o' && DT_CC == 'i' /* Not sure about this one */ /* Do nothing */ #endif /* Fixed-size types */ #ifdef HAVE_INTTYPES # include #endif typedef int8_t Int8; typedef int16_t Int16; typedef int32_t Int32; typedef uint8_t UInt8; typedef uint16_t UInt16; typedef uint32_t UInt32; #include #include #include /* fopen() modes */ #define FOPEN_RB "rb" #define FOPEN_RBP "rb+" #define FOPEN_WB "wb" #define FOPEN_RT "r" #define FOPEN_WT "w" #define FOPEN_AT "a" #define FOPEN_AB "a" /* Number of bytes to read from or write to a file */ typedef unsigned long iolen_t; #define MEMORYCACHE (0x8000L) /* steps to increase size of WAD directory*/ #define MAXPWADDIR (128) /*Add 64000 bytes of pure junk, because of a bug in DEU5.21 */ #define MAXJUNK64 (1000) /*special value, means int is not valid*/ #define INVALIDINT (-6666) /*indicate an extern WAD entry*/ #define EXTERNAL (0x80000000L) typedef Int16 Bool; #define TRUE 1 #define FALSE 0 /* Wad magic numbers */ #define IWADMAGIC 0x5749 /* little-endian 16-bit int for "IW" */ #define PWADMAGIC 0x5750 /* little-endian 16-bit int for "PW" */ #define WADMAGIC 0x4441 /* little-endian 16-bit int for "AD" */ /*type of WAD files. correspond to 1st half of name*/ typedef Int16 WADTYPE; #define IWAD (IWADMAGIC) #define PWAD (PWADMAGIC) /* Number of entries in the game palette */ #define NCOLOURS 256 /************ deutex.c ************/ /* Entry selection Bits*/ typedef Int16 NTRYB; #define BLEVEL (0x0001) #define BLUMP (0x0002) #define BSOUND (0x0004) #define BTEXTUR (0x0008) #define BGRAPHIC (0x0010) #define BSPRITE (0x0020) #define BPATCH (0x0040) #define BFLAT (0x0080) #define BMUSIC (0x0100) #define BSNEAP (0x0200) #define BSNEAT (0x0400) #define BSCRIPT (0x0800) #define BSNEA (BSNEAP|BSNEAT) #define BWALL (0x1000) #define BALL (0x7FFF) typedef Int16 SNDTYPE; #define SNDNONE (0) #define SNDAU (1) #define SNDWAV (2) #define SNDVOC (3) typedef Int16 IMGTYPE; #define PICNONE (0) #define PICBMP (1) #define PICGIF (2) #define PICPPM (3) #define PICTGA (4) #define PICWAD (5) /****************** mkwad.c ********************/ /*wad directory*/ struct WADDIR /*same as in doom*/ { Int32 start; /*start of entry*/ Int32 size; /*size of entry*/ char name[8]; /*name of entry*/ }; struct WADINFO { Int32 ntry; /*entries in dir*/ Int32 dirpos; /*position of dir*/ struct WADDIR *dir; /*directory */ Int32 maxdir; /*max nb of entry in dir*/ Int32 wposit; /*position for write*/ Int32 maxpos; /*farther referenced byte in WAD*/ FILE *fd; /* File pointer */ char *filename; /* Pointer on block malloc'd by WADRopen*() and free'd by WADRclose() and containing the name of the file. */ Bool ok; /*security ok&1=read ok&2=write*/ }; /********************ident.c********************/ typedef Int16 PICTYPE; #define PGRAPH 0x02 #define PWEAPN 0x04 #define PSPRIT 0x06 #define PPATCH 0x08 #define PFLAT 0x0a #define PLUMP 0x0c #define PSNEAP 0x0d #define PSNEAT 0x0e #define PWALL 0x10 typedef Int16 ENTRY; #define EMASK 0xFF00 #define EVOID 0x0000 #define ELEVEL 0x0100 #define EMAP 0x0200 /*Levels (doom1) and Maps(Doom2)*/ #define ELUMP 0x0300 #define ETEXTUR 0x0400 #define EPNAME 0x0500 /*textures*/ #define ESOUND 0x0600 #define ESNDPC 0x0601 #define ESNDWAV 0x0602 #define EGRAPHIC 0x0700 #define ESPRITE 0x0800 #define EPATCH 0x0900 #define EPATCH1 0x0901 #define EPATCH2 0x0902 #define EPATCH3 0x0903 #define EFLAT 0x0A00 #define EFLAT1 0x0A01 #define EFLAT2 0x0A02 #define EFLAT3 0x0A03 #define EMUSIC 0x0B00 #define EDATA 0x1000 #define ESNEA 0x2000 #define ESNEAP 0x2001 /* Snea using PLAYPAL */ #define ESNEAT 0x2002 /* Snea using TITLEPAL */ #define ESSCRIPT 0x3000 /* Strife script (SCRIPTnn) */ #define EWALL 0x4000 /* ROTT wall (WALLSTRT/WALLSTOP) */ #define EZZZZ 0x7F00 /*unidentified entries*/ /******************* lists.c ********************/ /*deutex.c: misc*/ Bool LetsHaveFunBaby(long guesswhat); /*compose.c: TEXTURE list*/ /*compose.c: TEXTURE insertion...rather, WAD composition*/ void CMPOmakePWAD(const char *doomwad,WADTYPE type, const char *PWADname, const char *DataDir, const char *texin,NTRYB select, char trnR, char trnG, char trnB,Bool George); /*substit.c: DOOM.EXE string substitution*/ void EXE2list(FILE *out,char *doomexe,Int32 start,Int16 thres); void EXEsubstit(const char *texin,const char *doomexe,Int32 start,Int16 thres); void XTRlistDir(const char *doomwad,const char *wadin,NTRYB select); void XTRvoidSpacesInWAD(const char *wadin); void XTRcompakWAD(const char *DataDir, const char *wadin, const char *texout,Bool ShowIdx); void XTRstructureTest(const char *doomwad, const char *wadin); void XTRtextureUsed(const char *wadin); /* * Types defined elsewhere */ struct cusage_s; typedef struct cusage_s cusage_t; /* * Misc globals, set by command line arguments */ typedef enum { PF_NORMAL, PF_ALPHA, PF_PR, PF_ROTT } picture_format_t; typedef enum { TF_NORMAL, TF_NAMELESS, TF_NONE, TF_STRIFE11 } texture_format_t; typedef enum { TL_NORMAL, TL_TEXTURES, TL_NONE } texture_lump_t; typedef enum { RP_REJECT, RP_FORCE, RP_WARN, RP_ACCEPT } rate_policy_t; typedef enum { CLOBBER_YES, CLOBBER_NO, CLOBBER_ASK } clobber_t; extern picture_format_t picture_format; extern texture_format_t input_texture_format; extern texture_format_t output_texture_format; extern texture_lump_t texture_lump; extern rate_policy_t rate_policy; extern clobber_t clobber; extern const char *debug_ident; extern int old_music_ident_method; extern const char *palette_lump; extern const char *logfile; deutex-4.4.902/src/endianio.h0000644000324500032450000000124010301445363015312 0ustar aymaym00000000000000/* * endianio.h - file I/O with explicit endianness * * Those functions allow to read little-endian and * big-endian integers from a file regardless of the * endianness of the CPU. * * Adapted from Yadex by AYM on 1999-03-06. */ int fread_i16_le (FILE *fd, int16_t *buf); int fread_i16_be (FILE *fd, int16_t *buf); int fread_i32_le (FILE *fd, int32_t *buf); int fread_i32_be (FILE *fd, int32_t *buf); int fread_u16_le (FILE *fd, uint16_t *buf); int fwrite_i16_le (FILE *fd, int16_t buf); int fwrite_i16_be (FILE *fd, int16_t buf); int fwrite_i32_le (FILE *fd, int32_t buf); int fwrite_i32_be (FILE *fd, int32_t buf); int fwrite_u16_le (FILE *fd, uint16_t buf); deutex-4.4.902/src/endianm.h0000644000324500032450000000141307032764266015156 0ustar aymaym00000000000000/* * endianm.h * Endianness-independant memory access. * * Those functions allow to retrieve little-endian and * big-endian integers from a memory area regardless of * the endianness of the CPU. * * AYM 1999-07-04 */ /* Use the names DeuTex provides */ #ifndef i16 # define i16 Int16 #endif #ifndef i32 # define i32 Int32 #endif #ifndef u16 # define u16 UInt16 #endif #ifndef u32 # define u32 UInt32 #endif void read_i16_le (const void *ptr, i16 *buf); void read_i32_le (const void *ptr, i32 *buf); i16 peek_i16_le (const void *ptr); u16 peek_u16_le (const void *ptr); i32 peek_i32_be (const void *ptr); i32 peek_i32_le (const void *ptr); void write_i16_le (void *ptr, i16 val); void write_i32_be (void *ptr, i32 val); void write_i32_le (void *ptr, i32 val); deutex-4.4.902/src/extract.h0000644000324500032450000000310107230110511015163 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /*extract.c: list dir and extract entries*/ void XTRextractWAD(const char *doomwad, const char *DataDir, const char *wadin, const char *texout, IMGTYPE Picture,SNDTYPE Sound,Bool fullSND,NTRYB select, char trnR, char trnG, char trnB,Bool WSafe, cusage_t *cusage); /*extract.c: get a single entry*/ void XTRgetEntry(const char *doomwad, const char *DataDir, const char *wadin, const char *entry, IMGTYPE Picture,SNDTYPE Sound,Bool fullSND, char trnR, char trnG, char trnB); /*obsolete junk*/ void XTRtextureList(char *doomwad,char *DataDir); void XTRpatchList(char *doomwad,char *DataDir,IMGTYPE Picture, char trnR, char trnG, char trnB); deutex-4.4.902/src/gifcodec.h0000644000324500032450000000130107032764266015302 0ustar aymaym00000000000000/* The LZW CODEC for GIF is Copyright (c) 1995 David Kaplan The Graphics Interchange Format(c) is the Copyright property of CompuServe Incorporated. */ /* initialise encoder. declare the output file */ Int16 InitEncoder(FILE* out, Int16 bpp); /*bpp=8*/ /* encode a buffer of 256 characters, and write it to output file */ Int16 Encode(UInt8 *buf, Int32 size); /* last operation to do, when the coding is finished */ Int16 ExitEncoder(void); /* Init decoder input file, codebits=8, pixelcount=8? */ Int16 InitDecoder( FILE* infile, Int16 codebits, Int16 rowsize); /* decode a buffer */ Int16 Decode( UInt8 *buf, Int16 npxls ); /* last operation */ void ExitDecoder(void); deutex-4.4.902/src/ident.h0000644000324500032450000000345607333247415014653 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* DOOM specifics*/ /* Entry Identification */ ENTRY *IDENTentriesIWAD(struct WADINFO *wad,char *Pnam,Int32 Pnamsz,Bool Fast); ENTRY *IDENTentriesPWAD(struct WADINFO *wad,char *Pnam,Int32 Pnamsz); Int16 IDENTlevel(const char *buffer); /* Level Part Identification */ int IDENTlevelPart(const char *name); /* Insertion point determination*/ Int16 IDENTinsrY(PICTYPE type,Int16 insrY,Int16 szy); Int16 IDENTinsrX(PICTYPE type,Int16 insrX,Int16 szx); ENTRY IDENTsneap (struct WADINFO *info, Int16 n); const char *entry_type_name (ENTRY type); /* For EFLATS, return "flat" */ const char *entry_type_plural (ENTRY type); /* For EFLATS, return "flats" */ const char *entry_type_dir (ENTRY type); /* For EFLATS, return "flats" */ const char *entry_type_section (ENTRY type); /* For EFLATS, return "flats" */ PICTYPE entry_type_pictype (ENTRY type); /* For EFLATS, return PFLAT */ deutex-4.4.902/src/lists.h0000644000324500032450000000226007230110521014655 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /*function to merge two WAD directories (complex)*/ struct WADDIR *LISmergeDir(Int32 *pNtry, Bool OnlySF, Bool Complain, NTRYB select, struct WADINFO *iwad, ENTRY *iiden, Int32 iwadflag, struct WADINFO *pwad,ENTRY *piden,Int32 pwadflag); deutex-4.4.902/src/log.h0000644000324500032450000000027510305102011014274 0ustar aymaym00000000000000/* * log.h * AYM 2001-02-02 */ int lopen (void); void lputc (char c); void lputs (const char *str); void lprintf (const char *fmt, ...); void vlprintf (const char *fmt, va_list list); deutex-4.4.902/src/merge.h0000644000324500032450000000272107230110524014623 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /*merge a WAD into an IWAD*/ void PSTmergeWAD(const char *doomwad, const char *wadin,NTRYB select); /*put all sprites in another WAD, like DMADDS*/ void ADDallSpriteFloor(const char *wadout,const char *doomwad,const char *wadin,NTRYB select); /*append all sprites*/ void ADDappendSpriteFloor(const char *doomwad,const char *wadin,NTRYB select); /*join two WADs, including textures and pnames*/ void ADDjoinWads(const char *doomwad,const char *wadres,const char *wadext,NTRYB select); /*restore a modified WAD*/ void HDRrestoreWAD(const char *wadres); deutex-4.4.902/src/mkwad.h0000644000324500032450000000772407230110530014634 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /*for merging directories*/ void WADRopenPipo(struct WADINFO *info,Int32 ntry); struct WADDIR *WADRclosePipo(struct WADINFO *info,Int32 *ntry); Int32 WADRdirAddPipo(struct WADINFO *info,Int32 start,Int32 size,const char *entry); /*Open a WAD file for read*/ void WADRopenR(struct WADINFO *info, const char *wadin); /*Open a WAD file for write*/ void WADRopenW(struct WADINFO *info, const char *wadout, WADTYPE type, int verbose); /*Open a WAD file for append*/ void WADRopenA(struct WADINFO *info, const char *wadinout); /*Close a WAD file*/ void WADRclose(struct WADINFO *info); /*WAD file structure*/ /*set position of internal WAD directory*/ void WADRsetDirRef(struct WADINFO *info,Int32 ntry,Int32 dirpos); /*change size of a WAD*/ void WADRchsize(struct WADINFO *info,Int32 fsize); /*increase size of WAD, do not update position*/ Bool WADRchsize2(struct WADINFO *info,Int32 fsize); /*composition of internal WAD directory*/ /*add an entry to the directory*/ Int32 WADRdirAddEntry(struct WADINFO *info,Int32 start,Int32 size, const char *name); /*write the directory (and set it's position)*/ void WADRwriteDir(struct WADINFO *info, int verbose); /*find an entry in the directory*/ Int16 WADRfindEntry(struct WADINFO *info, const char *entry); /*-1 or index of entry in directory*/ /*set data in a WAD (write position doesn't change)*/ void WADRsetLong(struct WADINFO *info,Int32 pos,Int32 val); void WADRsetShort(struct WADINFO *info,Int32 pos,Int16 val); /*align on long*/ void WADRalign4(struct WADINFO *info); /*align on long word, for next entry*/ /*tell position of pointer*/ Int32 WADRposition(struct WADINFO *info); /*current position*/ /*write date (write position increase)*/ Int32 WADRwriteLong(struct WADINFO *info,Int32 val); Int32 WADRwriteShort(struct WADINFO *info,Int16 val); Int32 WADRwriteBytes(struct WADINFO *info,char *data,Int32 size); Int32 WADRwriteBytes2(struct WADINFO *info,char *data,Int32 size); Int32 WADRwriteLump(struct WADINFO *info,const char *file); Int32 WADRwriteWADbytes(struct WADINFO *info,struct WADINFO *src,Int32 start,Int32 size); Int32 WADRwriteWADentry(struct WADINFO *info,struct WADINFO *src,Int16 n); void WADRwriteWADlevelParts(struct WADINFO *info,struct WADINFO *src,Int16 n, size_t nlumps); void WADRwriteWADlevel(struct WADINFO *info,const char *file,const char *level); /*read data*/ void WADRseek(struct WADINFO *info,Int32 position); iolen_t WADRreadBytes(struct WADINFO *info,char *buffer,iolen_t nbytes); iolen_t WADRreadBytes(struct WADINFO *info,char *buffer,iolen_t nbytes); Int16 WADRreadShort(struct WADINFO *info); Int32 WADRreadLong(struct WADINFO *info); char *WADRreadEntry(struct WADINFO *info,Int16 N,Int32 *psize); char *WADRreadEntry2 (struct WADINFO *info, Int16 n, Int32 *psize); void WADRsaveEntry(struct WADINFO *info,Int16 N, const char *file); /*make some preparations before appending data to an existing WAD*/ /*so that it can be restored later*/ Int32 WADRprepareAppend(const char *wadres,struct WADINFO *rwad,struct WADDIR *NewDir,Int32 NewNtry, Int32 *dirpos,Int32 *ntry, Int32 *size); deutex-4.4.902/src/picture.h0000644000324500032450000000377010303346034015206 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* first call COLinit();*/ Bool PICsaveInFile (char *file, PICTYPE type, char *pic, Int32 picsz, Int16 *pXinsr, Int16 *pYinsr, IMGTYPE Picture, const char *name, cusage_t *cusage); Int32 PICsaveInWAD(struct WADINFO *info,char *file,PICTYPE type,Int16 Xinsr,Int16 Yinsr,IMGTYPE Picture); /* last call COLfree();*/ /*picture.c: only for test*/ void GIFtoBMP(char *file,char *bmpdir,char *name); void BMPtoGIF(char *file,char *bmpdir,char *name); /* * pic_head_t * parse_pic_header() returns header information * through this structure. */ typedef struct { Int16 width; /* Width of picture */ Int16 height; /* Height of picture */ Int16 xofs; /* X-offset of picture */ Int16 yofs; /* Y-offset of picture */ const void *colofs; /* Pointer on array of column offsets */ const unsigned char *data; /* Pointer on column data */ size_t colofs_size; /* Size of a column offset in bytes (2 or 4) */ int dummy_bytes; /* Are there dummy bytes around post data ? */ } pic_head_t; int parse_pic_header (const char *buf, long size, pic_head_t *h, char *message); deutex-4.4.902/src/sound.h0000644000324500032450000000244407571232212014665 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /********************* sound.c *******************/ void SNDsaveSound(char *file,char *buffer,Int32 size,SNDTYPE Sound, Bool fullSND, const char *name); Int32 SNDcopyInWAD(struct WADINFO *info,char *file,SNDTYPE Sound); void SNDsavePCSound(const char *name, const char *file, const char *buffer, Int32 size); Int32 SNDcopyPCSoundInWAD(struct WADINFO *info,char *file); deutex-4.4.902/src/sscript.h0000644000324500032450000000020507107267232015222 0ustar aymaym00000000000000/* * sscript.h * AYM 2000-05-13 */ int sscript_save (struct WADINFO *wad, Int16 n, const char *file); int sscript_load (void); deutex-4.4.902/src/text.h0000644000324500032450000000465410301075221014514 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* ** simplified TEXT parsing */ struct TXTFILE { FILE *fp; Int16 Lines; Int16 LastChar; Int16 SectionStart; Int16 SectionEnd; char Section[8]; char pathname[1]; }; /* A special instance of struct TXTFILE that is treated by the TXT*() output functions as the equivalent of /dev/null. Writing into it is a no-op. This convention is _not_ supported by the input functions ! */ extern struct TXTFILE TXTdummy; /* ** For any Reading of TEXT files */ void TXTinit(void); struct TXTFILE *TXTopenR(const char *file, int silent); void TXTcloseR(struct TXTFILE *TXT); /* ** To read entries */ Bool TXTskipComment(struct TXTFILE *TXT); Bool TXTseekSection(struct TXTFILE *TXT,const char *def); Bool TXTentryParse(char *name,char *filenam,Int16 *x,Int16 *y,Bool *repeat, struct TXTFILE *TXT, Bool XY); /* ** To read textures */ Bool TXTreadTexDef(struct TXTFILE *TXT,char name[8],Int16 *szx,Int16 *szy); Bool TXTreadPatchDef(struct TXTFILE *TXT,char name[8],Int16 *ofsx,Int16 *ofsy); /* ** To read PC sounds */ Int16 TXTreadShort(struct TXTFILE *TXT); /* ** For any Writing of text files */ struct TXTFILE *TXTopenW(const char *file); /*open, and init if needed*/ void TXTcloseW(struct TXTFILE *TXT); /* ** To write entries */ void TXTaddSection(struct TXTFILE *TXT,const char *def); void TXTaddEntry(struct TXTFILE *TXT,const char *name,const char *filenam,Int16 x,Int16 y,Bool repeat, Bool XY); void TXTaddComment(struct TXTFILE *TXT,const char *text); void TXTaddEmptyLine (struct TXTFILE *TXT); deutex-4.4.902/src/texture.h0000644000324500032450000000426010304145436015232 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2001 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /*****************texture.c**********************/ /** PNM module **/ void PNMinit(char *buffer,Int32 size); Int16 PNMindexOfPatch(char *patch); /* check if patch exists. for ident.c*/ Int32 PNMwritePNAMEtoWAD(struct WADINFO *info); /* write PNAME entry in Wad*/ void PNMfree(void); Int16 PNMgetNbOfPatch(void); /* compose.c get nb of patches*/ void PNMgetPatchName(char name[8],Int16 index); /* compose.c returns name of patch, from index*/ Bool PNMisNew(Int16 idx); /* compose.c is the patch not in IWAD? */ /** TXU module **/ void TXUinit(void); /*requires the the patches are init*/ void TXUfree(void); Bool TXUexist(char *Name); /*does it exist?*/ Int32 TXUwriteTEXTUREtoWAD(struct WADINFO *info); /*write the TEXTURE entry in Wad*/ void TXUreadTEXTURE(const char *texture1_name, const char *Data, Int32 DataSz, const char *Patch, Int32 PatchSz, Bool Redefn); /*read texture from raw data = TEXTURE entry */ void TXUwriteTexFile(const char *file); /*write the TEXTURE entry to a file*/ void TXUreadTexFile(const char *file,Bool Redefn); /*checkif the composition of textues in okay*/ Bool TXUcheckTex(Int16 npatch,Int16 *PszX); /*declare a fake texure. to list textures*/ void TXUfakeTex(char Name[8]); /*list all defined textures*/ void TXUlistTex(void); deutex-4.4.902/src/tools.h0000644000324500032450000000601510303336032014663 0ustar aymaym00000000000000/* This file is part of DeuTex. DeuTex incorporates code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. DeuTex is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #define MSGCLASS_INFO 'i' #define MSGCLASS_WARN 'w' #define MSGCLASS_ERR 'E' #define MSGCLASS_BUG 'B' void check_types (void); void PrintCopyright (void); void print_version (void); void NoCommandGiven (void); char *fnameofs (const char *name, long ofs); char *fname (const char *name); char *lump_name (const char *name); char *short_dump (const char *data, size_t size); const char *quotechar (char c); void PrintInit(Bool asFile); void PrintVerbosity(Int16 level); void PrintExit(void); void ProgErrorCancel(void); void ProgErrorAction(void (*action)(void)); void ProgError (const char *code, const char *fmt, ...); /*fatal error. halt.*/ void nf_err (const char *code, const char *fmt, ...); /* Non-fatal error */ void Bug (const char *code, const char *fmt, ...); /*fatal bug. halt*/ void Warning (const char *code, const char *str, ...); /*I'm not happy*/ void LimitedWarn (int *left, const char *code, const char *fmt, ...); void LimitedEpilog (int *left, const char *code, const char *fmt, ...); void Output (const char *fmt, ...); /*command text output*/ void Info (const char *code, const char *fmt, ...); /*useful indications*/ void Phase (const char *code, const char *fmt, ...); /*phase of executions*/ void Detail (const char *code, const char *fmt, ...); /*technical details*/ /******************tools.c***********************/ /** FILE name , for lumps and BMP **/ void ToLowerCase(char *file); void MakeDir(char file[128], const char *path, const char *dir, const char *sdir); Bool MakeFileName(char file[128], const char *path, const char *dir, const char *sdir, const char *name, const char *extens); void GetNameOfWAD(char name[8], const char *path); Int16 Chsize(int handle,Int32 newsize); Int32 GetFileTime(const char *path); void SetFileTime(const char *path, Int32 time); void Unlink(const char *file); void Memcpy (void *dest,const void *src, long n); void Memset (void *dest,char car, long n); void *Malloc (long size); void *Realloc (void *old, long size); void Free( void *); void Normalise(char dest[8], const char *src); void Progress(void); void ProgressEnds(void); deutex-4.4.902/src/usedidx.h0000644000324500032450000000130207032764266015205 0ustar aymaym00000000000000/* * usedidx.h * Palette index usage statistics (cf -usedidx) */ #ifndef DT_USEDIDX_H #define DT_USEDIDX_H /* This block is used in conjunction with -usedidx. Avoid messing with its fields directly. Use the API instead. */ struct cusage_s { /* Per-lump: */ char lump_name[8]; unsigned long *lump_uses; /* Totals: */ unsigned long uses[NCOLOURS]; unsigned long nlumps[NCOLOURS]; char where_first[NCOLOURS][8]; }; void usedidx_begin_lump (cusage_t *cusage, const char *name); void usedidx_pixel (cusage_t *cusage, unsigned char idx); void usedidx_end_lump (cusage_t *cusage); void usedidx_rectangle (const char *buf, long buf_size, const char *name, cusage_t *cusage); #endif deutex-4.4.902/src/wadio.h0000644000324500032450000000070107032764266014645 0ustar aymaym00000000000000/* * wadio.h * Wad low level I/O routines * AYM 1999-03-06 */ void set_output_wad_endianness (int big_endian); void set_input_wad_endianness (int big_endian); extern int (* wad_write_i16) (FILE *, Int16); extern int (* wad_write_i32) (FILE *, Int32); extern int (* wad_read_i16) (FILE *, Int16 *); extern int (* wad_read_i32) (FILE *, Int32 *); int wad_read_name (FILE *fd, char name[8]); int wad_write_name (FILE *fd, const char *name); deutex-4.4.902/src/deusf.def0000644000324500032450000000021005644376304015151 0ustar aymaym00000000000000NAME DEUSF CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD MOVEABLE MULTIPLE HEAPSIZE 2048 STACKSIZE 8192 deutex-4.4.902/src/deusfos.def0000644000324500032450000000016405700402630015504 0ustar aymaym00000000000000NAME DEUSFOS WINDOWCOMPAT DESCRIPTION 'DEUSFOS' PROTMODE HEAPSIZE 32768 STACKSIZE 16384 deutex-4.4.902/src/deutex.def0000644000324500032450000000021105660234212015327 0ustar aymaym00000000000000NAME DEUTEX CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD MOVEABLE MULTIPLE HEAPSIZE 2048 STACKSIZE 8192 deutex-4.4.902/src/deutexos.def0000644000324500032450000000016605705046630015707 0ustar aymaym00000000000000NAME DEUTEXOS WINDOWCOMPAT DESCRIPTION 'DEUTEXOS' PROTMODE HEAPSIZE 32768 STACKSIZE 16384 deutex-4.4.902/src/color.c0000644000324500032450000003313410304422012014631 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /*select your quantisation method*/ /*#define QUANTSLOW*/ #define QUANTHASH #include "deutex.h" #include "tools.h" #include "color.h" /*compile only for DeuTex*/ #if defined DeuTex #ifdef QUANTHASH /*************** COL module: quantisation ************/ /* ** hash table ** */ UInt8 COLindex( UInt8 R, UInt8 G, UInt8 B,UInt8 index); static UInt8 COLpalMatch( UInt8 R, UInt8 G, UInt8 B); static struct PIXEL *COLpal; /* The game palette (comes from PLAYPAL) */ static struct PIXEL *COLpalAlt = NULL; /* Alternate palette (TITLEPAL) */ static struct PIXEL COLinv; static UInt8 COLinvisib; static Bool COLok=FALSE; /* * pixel_cmp * Compare two PIXEL structures à la memcmp() */ static int pixel_cmp (const void *pixel1, const void *pixel2) { const struct PIXEL *const p1 = (const struct PIXEL *) pixel1; const struct PIXEL *const p2 = (const struct PIXEL *) pixel2; if (p1->R != p2->R) return p1->R - p2->R; if (p1->G != p2->G) return p1->G - p2->G; if (p1->B != p2->B) return p1->B - p2->B; return 0; } const int COLsame = 3; /* * COLdiff - compute the distance between two colours * * Return a number between 0 (closest) and 24384 (farthest). */ #if 1 Int16 COLdiff( UInt8 R, UInt8 G, UInt8 B, UInt8 idx) { register struct PIXEL *pixel = &COLpal[(Int16)(idx&0xFF)]; register Int16 d; /*signed*/ register Int16 e=0; d= (((Int16)R)&0xFF) - (((Int16) pixel->R) &0xFF); d>>=1; e+= d*d; d= (((Int16)G)&0xFF) - (((Int16) pixel->G) &0xFF); d>>=1; e+= d*d; d= (((Int16)B)&0xFF) - (((Int16) pixel->B) &0xFF); d>>=1; e+= d*d; if(e<0) return 0x7FFF; return e; } #else #define COLdiff(r, g, b, idx)\ ( \ ( \ ((long) (r) - COLpal[idx].R) * ((long) (r) - COLpal[idx].R) \ + ((long) (g) - COLpal[idx].G) * ((long) (g) - COLpal[idx].G) \ + ((long) (b) - COLpal[idx].B) * ((long) (b) - COLpal[idx].B) \ ) \ >> 3 \ ) #endif static UInt8 COLpalMatch( UInt8 R, UInt8 G, UInt8 B) { Int16 i,test,min=0x7FFF; UInt8 idxmin='\0'; if(COLok!=TRUE) Bug("PL24", "COLok"); for(i=0;i<256;i++) { if((UInt8)i!=COLinvisib) { test=COLdiff(R,G,B,(UInt8)i); if(test>8; res &= HashMask; return (Int16) res; } /* void COLhashPrint(void) { Int16 idx,i; UInt8 res; UInt8 buff[64]; Int16 count=0; for(idx=0;idx2) { if(res==COLhash[(nextidx-1)&HashMask]) fprintf(COLfp,"multi %d in %d\n",(int)res,nextidx); idx=((Int16)res)&0xFF; fprintf(COLfp,"%d\t%d\t%d\t*\n",(int)(R-COLpal[idx].R),(int)(G-COLpal[idx].G),(int)(B-COLpal[idx].B)); } */ return res; } } /*no good solution. slow match*/ return COLpalMatch(R,G,B); } /* * Normal palette (PLAYPAL) */ void COLinit( UInt8 invR, UInt8 invG, UInt8 invB,char *Colors, Int16 Colsz, const char *pathname, const char *lumpname) { Int16 i; const char *name = NULL; /*Int16 R,G,B;*/ if(COLok!=FALSE) Bug("PL02", "COLok"); if(Colsz< 256*sizeof(struct PIXEL)) if (lumpname == NULL) ProgError ("PL03", "%s: wrong size for PLAYPAL", fname (pathname)); else ProgError ("PL04", "%s: %s: wrong size for PLAYPAL", fname (pathname), lump_name (lumpname)); COLok=TRUE; COLpal= (struct PIXEL *)Malloc(256*sizeof(struct PIXEL)); for(i=0;i< NCOLOURS;i++) { COLpal[i].R=Colors[i*3+0]; COLpal[i].G=Colors[i*3+1]; COLpal[i].B=Colors[i*3+2]; } #if 1 /*supposedly exact...*/ if (COLpal[0].R == 0 && COLpal[0].G == 0 && COLpal[0].B == 0 && COLpal[0xf7].R == 0 && COLpal[0xf7].G == 0 && COLpal[0xf7].B == 0) { i = 0xf7; name = "Doom"; } else if (COLpal[35].R == 255 && COLpal[35].G == 255 && COLpal[35].B == 255 && COLpal[255].R == 255 && COLpal[255].G == 255 && COLpal[255].B == 255) { i = 0xff; name = "Heretic"; } #if 0 else if (0) /* FIXME */ { name = "Hexen"; } #endif else if (COLpal[0].R == 0 && COLpal[0].G == 0 && COLpal[0].B == 0 && COLpal[240].R == 0 && COLpal[240].G == 0 && COLpal[240].B == 0) { i = 0xf0; name = "Strife"; } else { i = 0xff; name = NULL; } #else /*screws some little points, on some sprites*/ i=0xFF; /*DOOM and HERETIC*/ #endif /* ** correction to doom palette */ COLinvisib= (UInt8)(i&0xFF); Info("PL05", "Palette is %s", name ? name : "(unknown)"); if (name == NULL) { Warning("PL06","Unknown palette, using colour 0xff as transparent colour"); Warning ("PL06", "Some graphics may appear moth-eaten"); } COLinv.R=COLpal[i].R=invR; COLinv.G=COLpal[i].G=invG; COLinv.B=COLpal[i].B=invB; /* Init hash table. We take special care of hashing only unique RGB triplets. This precaution is unnecessary for Doom, Heretic, Hexen and Strife but Doom alpha O.2, 0.4 and 0.5 have a PLAYPAL that contains many duplicates that would fill the hash table with useless data. -- AYM 1999-09-18 */ { struct PIXEL *unique = Malloc (NCOLOURS * sizeof *unique); for (i = 0; i < NCOLOURS; i++) unique[i] = COLpal[i]; qsort (unique, NCOLOURS, sizeof *unique, pixel_cmp); COLhash=(UInt8 *)Malloc(HashSz); Memset(COLhash,COLinvisib,HashSz); /*clear hash table*/ for (i = 0; i< NCOLOURS; i++) { if ((UInt8)i!=COLinvisib && (i == 0 || pixel_cmp (unique + i, unique + i - 1) != 0)) COLputColHash (i, unique[i].R, unique[i].G, unique[i].B); } Free (unique); } } void COLfree(void) { if(COLok!=TRUE) Bug("PL99", "COLok"); COLok=FALSE; Free(COLpal); Free(COLhash); if (COLpalAlt != NULL) Free (COLpalAlt); } UInt8 COLinvisible(void) { if(COLok!=TRUE) Bug("PL27", "COLok"); return COLinvisib; } struct PIXEL *COLdoomPalet(void) { if(COLok!=TRUE) Bug("PL20", "COLok"); return COLpal; } UInt8 COLindex( UInt8 R, UInt8 G, UInt8 B, UInt8 index) { Int16 i; if(COLok!=TRUE) Bug("PL23", "COLok"); /*check for invisible color*/ if(R==COLinv.R && G==COLinv.G && B==COLinv.B) return COLinvisib; /*check for DOOM palette*/ i= ((Int16)index)&0xFF; if(R==COLpal[i].R) if(G==COLpal[i].G) if(B==COLpal[i].B) return index; /*else, check hash palette*/ i=(Int16)COLgetIndexHash(R,G,B); return (UInt8)i; } #endif /*QUANTHASH*/ /* * Alternate palette (TITLEPAL) */ static char *titlepal_data = NULL; static size_t titlepal_size = 0; void COLinitAlt (char *_titlepal_data, Int32 _titlepal_size) { titlepal_data = _titlepal_data; titlepal_size = _titlepal_size; } struct PIXEL *COLaltPalet(void) { if (COLpalAlt != NULL) return COLpalAlt; /* What follows is done only once : */ if (titlepal_data == NULL) { int n; Warning ("PL11", "TITLEPAL not found, using PLAYPAL instead"); COLpalAlt = (struct PIXEL *) Malloc (NCOLOURS * sizeof *COLpalAlt); for (n = 0; n < NCOLOURS; n++) COLpalAlt[n] = COLpal[n]; } else { struct PIXEL *p; struct PIXEL *pmax; const unsigned char *d = (const unsigned char *) titlepal_data; const unsigned char *dmax = d + titlepal_size; if (titlepal_size < 3 * NCOLOURS) Warning ("PL13", "TITLEPAL too short (%ld), filling with black", (long) titlepal_size); COLpalAlt = (struct PIXEL *) Malloc (NCOLOURS * sizeof *COLpalAlt); /* Copy the contents of TITLEPAL into COLpalAlt */ for (p = COLpalAlt, pmax = p + NCOLOURS; p < pmax; p++) { p->R = d < dmax ? *d++ : 0; p->G = d < dmax ? *d++ : 0; p->B = d < dmax ? *d++ : 0; } Free (titlepal_data); titlepal_data = NULL; /* Paranoia */ } return COLpalAlt; } #ifdef QUANTSLOW /*unused!*//*************** COL module: quantisation ************/ /* ** implemented as the most stupid color quantisation ** ever to be seen on this sector of the galaxy ** */ /*unused!*/ /*unused!*/ /*unused!*/static struct PIXEL *COLpal; /*unused!*/static struct PIXEL COLinv; /*unused!*/static UInt8 COLinvisib; /*unused!*/static Bool COLok=FALSE; /*unused!*/ /*unused!*/ /*unused!*/ /*unused!*/void COLinit( UInt8 invR, UInt8 invG, UInt8 invB,UInt8 *Colors, Int16 Colsz) /*unused!*/{ Int16 i; /*unused!*/ UInt8 r,g,b; /*unused!*/ /*unused!*/ if(COLok!=FALSE) Bug("XX99", "COLok"); /*unused!*/ if(Colsz< 256*sizeof(struct PIXEL)) Bug("XX99", "Color entry too small"); /*unused!*/ COLok=TRUE; /*unused!*/ COLpal= (struct PIXEL *)Malloc(256*sizeof(struct PIXEL)); /* ** possible bug: the color corresponding to the ** CYAN is assumed to be the second one with 0 0 0 ** this is because CYAN is supressed. */ /*unused!*/ for(i=0;i<256;i++) /*unused!*/ { r=Colors[i*3+0]; /*unused!*/ g=Colors[i*3+1]; /*unused!*/ b=Colors[i*3+2]; /*unused!*/ COLpal[i].R=r; /*unused!*/ COLpal[i].G=g; /*unused!*/ COLpal[i].B=b; /*unused!*/ if(r==0)if(g==0)if(b==0) /*unused!*/ COLinvisib=( UInt8)(i&0xFF); /*unused!*/ } /*unused!*/ if(COLinvisib!=(UInt8)0xF7)Warning("XX99", "Strange PLAYPAL invisible color"); /*unused!*/ if(COLinvisib==0)ProgError("XX99", "PLAYPAL is not correct"); /* ** correction to doom palette */ /*unused!*/ i=((Int16)COLinvisib)&0xFF; /*unused!*/ COLinv.R=COLpal[i].R=invR; /*unused!*/ COLinv.G=COLpal[i].G=invG; /*unused!*/ COLinv.B=COLpal[i].B=invB; /*unused!*/} /*unused!*/ UInt8 COLinvisible(void) /*unused!*/{ if(COLok!=TRUE) Bug("XX99", "COLok"); /*unused!*/ return COLinvisib; /*unused!*/} /*unused!*/ /*unused!*/struct PIXEL *COLdoomPalet(void) /*unused!*/{ if(COLok!=TRUE) Bug("XX99", "COLok"); /*unused!*/ return COLpal; /*unused!*/} /*unused!*/ /*unused!*/ /*unused!*/ /*unused!*/Int16 COLdiff( UInt8 r, UInt8 g, UInt8 b, UInt8 idx); /*unused!*/UInt8 COLindex( UInt8 R, UInt8 G, UInt8 B,UInt8 index) /*unused!*/{ Int16 i; /*unused!*/ Int16 test,min=0x7FFF; /*unused!*/ UInt8 idx,idxmin; /*unused!*/ if(COLok!=TRUE) Bug("XX99", "COLok"); /*unused!*/ /*unused!*/ if(R==COLinv.R)if(G==COLinv.G)if(B==COLinv.B) return COLinvisib; /*unused!*/ /*check for DOOM palette*/ /*unused!*/ i= ((Int16)index)&0xFF; /*unused!*/ if(R==COLpal[i].R) /*unused!*/ if(G==COLpal[i].G) /*unused!*/ if(B==COLpal[i].B) /*unused!*/ return index; /*unused!*/ /*Best color match: slow*/ /*unused!*/ idx=(UInt8)0; /*unused!*/ for(i=0;i<256;i++) /*unused!*/ { if(idx!=COLinvisib) /*unused!*/ { test=COLdiff(R,G,B,idx); /*unused!*/ if(test0)? d:-d; /*unused!*/ d= ((Int16)g) - ((Int16) COLpal[index].G); /*unused!*/ e+= (d>0)? d:-d; /*unused!*/ d= ((Int16)b) - ((Int16) COLpal[index].B); /*unused!*/ e+= (d>0)? d:-d; /*unused!*/ return e; /*unused!*/} #endif /*QUANTSLOW*/ #endif /*DeuTex*/ deutex-4.4.902/src/compose.c0000644000324500032450000004570510305367140015202 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include "tools.h" #include "mkwad.h" #include "texture.h" #include "ident.h" #include "color.h" #include "picture.h" #include "sound.h" #include "text.h" /*compile only for DeuTex*/ #if defined DeuTex static void AddSomeJunk(const char *file); /************Begin Tex2Ascii module ************************* ** ** Translate TEXTURE1,TEXTURE2 and PNAME in ** a texture list for future modifications */ extern char file[128]; /***************End Tex2ascii module ******************/ /* ** ** make a PWAD from creation directives ** load levels,lumps, ** create textures ** load sounds, pics, sprites, patches, flats, */ /* ** Can't handle PATCHES redefined from WAD */ static Bool CMPOcopyFromWAD ( Int32 *size, struct WADINFO *rwad, const char *DataDir, const char *Dir, const char *nam, const char *filenam ) { static struct WADINFO pwad; Int16 entry; if(MakeFileName(file,DataDir,Dir,"",filenam,"WAD")!=TRUE) return FALSE; WADRopenR(&pwad,file); entry=WADRfindEntry(&pwad,nam); if(entry>=0) { *size=WADRwriteWADentry(rwad,&pwad,entry); } WADRclose(&pwad); if(entry<=0)return FALSE; return TRUE; } /* ** find a picture. ** must=TRUE is picture must exist ** returns picture type */ static Int16 CMPOloadPic ( Int32 *size, struct WADINFO *rwad, char *file, const char *DataDir, const char *Dir, const char *nam, const char *filenam, Int16 Type, Int16 OfsX, Int16 OfsY ) { int res=PICNONE; if(MakeFileName(file,DataDir,Dir,"",filenam,"ppm")==TRUE) res=PICPPM; else if(MakeFileName(file,DataDir,Dir,"",filenam,"bmp")==TRUE) res=PICBMP; else if(MakeFileName(file,DataDir,Dir,"",filenam,"gif")==TRUE) { static int gif_warning = 0; res=PICGIF; if (! gif_warning) { Warning ("PC10", "GIF support may go away in the future"); gif_warning = 1; } } else if(CMPOcopyFromWAD(size,rwad,DataDir,Dir,nam,filenam)==TRUE) return PICWAD; if(res!=PICNONE) *size = PICsaveInWAD(rwad,file,Type,OfsX,OfsY,res); else if(Type!=PLUMP) Warning("PC90", "could not find file %s, .ppm, .bmp or .gif",file); return res; } struct WADINFO *CMPOrwad; const char *CMPOwadout=NULL; void CMPOerrorAction(void) { if(CMPOwadout==NULL) return; WADRclose(CMPOrwad); /*close file*/ Unlink(CMPOwadout); /*delete file*/ } void CMPOmakePWAD(const char *doomwad,WADTYPE type, const char *PWADname, const char *DataDir, const char *texin, NTRYB select, char trnR, char trnG, char trnB, Bool George) { /* ** type PWAD as we are generating a real PWAD */ Int32 start=0, size=0; static char name[8]; static char filenam[8]; /*PNAMES */ Int16 nbPatchs,p; Bool NeedPNAME=FALSE; Bool FoundOne=FALSE; Bool Repeat; IMGTYPE Picture; /*optional insertion point*/ Int16 X,Y; /*text file to read*/ static struct TXTFILE *TXT; /*DOOM wad*/ static struct WADINFO iwad,pwad; /*result wad file*/ static struct WADINFO rwad; /*for Pnames*/ Int16 entry;char *EntryP;Int32 EntrySz=0; /* initialisation*/ Info("CM01", "Composing %cWAD %s from %s", (type==IWAD) ? 'I' : 'P', fname (PWADname), texin); /*open iwad,get iwad directory*/ iwad.ok=0; WADRopenR(&iwad,doomwad); TXT= TXTopenR(texin, 0); WADRopenW(&rwad,PWADname,type, 1); /* fake IWAD or real PWAD */ /* ** dirty: set error handler to delete the wad out file, ** if an error occurs. */ CMPOrwad = &rwad; CMPOwadout = PWADname; ProgErrorAction(CMPOerrorAction); /* ** levels! add your own new levels to DOOM! ** read level from a PWAD file */ if(select&BLEVEL) { if(TXTseekSection(TXT,"LEVELS")) { while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE) { p=IDENTlevel(name); if(p<0) ProgError("CM11", "Illegal level name %s", lump_name (name)); if(MakeFileName(file,DataDir,"LEVELS","",filenam,"WAD")!=TRUE) ProgError("CM12", "Can't find level WAD %s", fname (file)); Detail("CM13", "Reading level WAD file %s", fname (file)); WADRwriteWADlevel(&rwad,file,name); } } } /* ** prepare palette for graphics */ /*find PLAYPAL*/ if(select&(BGRAPHIC|BSPRITE|BPATCH|BFLAT)) { /* If wadinfo.txt mentions a custom PLAYPAL, use that. Otherwise, use the one in the iwad. */ char *paldata = NULL; const char *playpal_pathname = NULL; const char *playpal_lumpname = NULL; if (TXTseekSection (TXT, "LUMPS")) { while (TXTentryParse(name, filenam, &X, &Y, &Repeat, TXT, FALSE) == TRUE) { if (strcmp (name, "PLAYPAL") == 0) { FILE *playpal_fp; MakeFileName (file, DataDir, "LUMPS", "", filenam, "LMP"); playpal_pathname = file; playpal_lumpname = NULL; EntrySz = 768; paldata = Malloc (EntrySz); playpal_fp = fopen (file, FOPEN_RB); if (playpal_fp == NULL) ProgError ("CM21", "%s: %s", fname (file), strerror (errno)); EntrySz = fread (paldata, 1, EntrySz, playpal_fp); if (EntrySz != 768) /* DEBUG was ProgError */ Warning ("CM22", "%s: short read", fname (file)); fclose (playpal_fp); break; } } } if (paldata == NULL) { playpal_pathname = iwad.filename; playpal_lumpname = palette_lump; entry = WADRfindEntry(&iwad, palette_lump); if (entry < 0) ProgError ("CM23", "Can't find %s in main WAD", lump_name (palette_lump)); paldata = WADRreadEntry (&iwad, entry, &EntrySz); } COLinit (trnR, trnG, trnB, paldata, (Int16) EntrySz, playpal_pathname, playpal_lumpname); Free (paldata); } /* ** ** lumps. non graphic raw data for DOOM */ if(select&BLUMP) { start=size=0; if(TXTseekSection(TXT,"LUMPS")) { Phase("CM30", "Making lumps"); while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE) { if(Repeat!=TRUE) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); if(MakeFileName(file,DataDir,"LUMPS","",filenam,"LMP")==TRUE) { size=WADRwriteLump(&rwad,file); } else { Picture=CMPOloadPic(&size,&rwad,file,DataDir,"LUMPS",name, filenam,PLUMP,X,Y); if(Picture==PICNONE) if(CMPOcopyFromWAD(&size,&rwad,DataDir,"LUMPS",name,filenam) !=TRUE) ProgError("CM31", "Can't find lump or picture file %s",file); } } WADRdirAddEntry(&rwad,start,size,name); } } } /* ** initialise list of patch names */ if(select&(BTEXTUR|BPATCH)) { entry=WADRfindEntry(&iwad,"PNAMES"); if(entry<0) ProgError("CM40", "Can't find PNAMES in main WAD"); EntryP=WADRreadEntry(&iwad,entry,&EntrySz); PNMinit(EntryP,EntrySz); Free(EntryP); NeedPNAME = FALSE; } /* ** read texture1 */ if(select&BTEXTUR) { if(TXTseekSection(TXT,"TEXTURE1")) { Phase("CM50", "Making TEXTURE1"); TXUinit(); entry=WADRfindEntry(&iwad,"TEXTURE1"); if(entry>=0) { EntryP=WADRreadEntry(&iwad,entry,&EntrySz); TXUreadTEXTURE("TEXTURE1", EntryP, EntrySz, NULL, 0, TRUE); Free(EntryP); } else Warning("CM51", "Can't find TEXTURE1 in main WAD"); FoundOne=FALSE; /*read TEXTURES composing TEXTURE1*/ while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE) { if(MakeFileName(file,DataDir,"TEXTURES","",name,"TXT")==TRUE) { Detail("CM52", "Reading texture file %s", fname (file)); TXUreadTexFile(file,TRUE); NeedPNAME=TRUE; FoundOne=TRUE; } else if(MakeFileName(file,DataDir,"TEXTURES","",name,"WAD")==TRUE) { Detail("CM53", "Reading texture WAD %s", fname (file)); WADRopenR(&pwad,file); entry=WADRfindEntry(&pwad,"TEXTURE1"); if(entry>=0) { EntryP=WADRreadEntry(&pwad,entry,&EntrySz); TXUreadTEXTURE("TEXTURE1", EntryP, EntrySz, NULL, 0, TRUE); Free(EntryP); NeedPNAME=TRUE; FoundOne=TRUE; } WADRclose(&pwad); } else ProgError("CM54", "Can't find texture list %s", file); } /*write texture*/ if(FoundOne==TRUE) { WADRalign4(&rwad); /*align entry on Int32 word*/ start= WADRposition(&rwad); size = TXUwriteTEXTUREtoWAD(&rwad); WADRdirAddEntry(&rwad,start,size,"TEXTURE1"); } TXUfree(); } } /* ** read texture2 */ if(select&BTEXTUR) { if(TXTseekSection(TXT,"TEXTURE2")) { Phase("CM55", "Making TEXTURE2"); TXUinit(); entry=WADRfindEntry(&iwad,"TEXTURE2"); if(entry>=0) { EntryP=WADRreadEntry(&iwad,entry,&EntrySz); TXUreadTEXTURE("TEXTURE2", EntryP, EntrySz, NULL, 0, TRUE); Free(EntryP); } else Warning("CM56", "Can't find TEXTURE2 in main WAD"); FoundOne=FALSE; /*read TEXTURES composing TEXTURE2*/ while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE) { if(MakeFileName(file,DataDir,"TEXTURES","",name,"TXT")==TRUE) { Detail("CM57", "Reading texture file %s", fname (file)); TXUreadTexFile(file,TRUE); NeedPNAME=TRUE; FoundOne=TRUE; } else if(MakeFileName(file,DataDir,"TEXTURES","",name,"WAD")==TRUE) { Detail("CM58", "Reading texture WAD %s", fname (file)); WADRopenR(&pwad,file); entry=WADRfindEntry(&pwad,"TEXTURE2"); if(entry>=0) { EntryP=WADRreadEntry(&pwad,entry,&EntrySz); TXUreadTEXTURE("TEXTURE2", EntryP, EntrySz, NULL, 0, TRUE); Free(EntryP); NeedPNAME=TRUE; FoundOne=TRUE; } WADRclose(&pwad); } else ProgError("CM59", "Can't find texture list %s", file); } /*write texture*/ if(FoundOne==TRUE) { WADRalign4(&rwad); /*align entry on Int32 word*/ start= WADRposition(&rwad); size = TXUwriteTEXTUREtoWAD(&rwad); WADRdirAddEntry(&rwad,start,size,"TEXTURE2"); } TXUfree(); } } /* ** PNAME */ if(select&BTEXTUR) { if(NeedPNAME) /*write PNAME in PWAD*/ { /*write entry PNAME*/ Phase("CM41", "Making PNAMES"); WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); size =PNMwritePNAMEtoWAD(&rwad); WADRdirAddEntry(&rwad,start,size,"PNAMES"); } } /* ** ** sounds. all sounds entries */ if(select&BSOUND) { start=size=0; if(TXTseekSection(TXT,"SOUNDS")) { Phase("CM60", "Making sounds"); while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE) { if(Repeat!=TRUE) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"TXT")==TRUE) { size=SNDcopyPCSoundInWAD(&rwad,file); Detail("CM62", "Reading PC sound from file %s", fname (file)); } else { if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"WAV")==TRUE) { size=SNDcopyInWAD(&rwad,file,SNDWAV); } else if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"AU")==TRUE) { size=SNDcopyInWAD(&rwad,file,SNDAU); } else if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"VOC")==TRUE) { size=SNDcopyInWAD(&rwad,file,SNDVOC); } else if(CMPOcopyFromWAD(&size,&rwad,DataDir,"SOUNDS",name, filenam)!=TRUE) ProgError("CM63", "Can't find sound %s, AU or WAV or VOC",file); Detail("CM64", "Reading sound file %s", fname (file)); } } WADRdirAddEntry(&rwad,start,size,name); } } } /* ** ** Musics */ if(select&BMUSIC) { start=size=0; if(TXTseekSection(TXT,"MUSICS")) { Phase("CM65", "Making musics"); while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE) { if(Repeat!=TRUE) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); /*Music*/ if(MakeFileName(file,DataDir,"MUSICS","",filenam,"MUS")==TRUE) { size=WADRwriteLump(&rwad,file); Detail("CM66", "Reading music file %s", fname (file)); } else if(CMPOcopyFromWAD(&size,&rwad,DataDir,"MUSICS",name, filenam)!=TRUE) ProgError("CM67", "Can't find music %s",file); } WADRdirAddEntry(&rwad,start,size,name); } } } /* ** ordinary graphics */ if(select&BGRAPHIC) { start=size=0; if(TXTseekSection(TXT,"GRAPHICS")) { Phase("CM70", "Making graphics"); while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE)==TRUE) { if(Repeat!=TRUE) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); Picture=CMPOloadPic(&size,&rwad,file,DataDir,"GRAPHICS",name, filenam,PGRAPH,X,Y); } WADRdirAddEntry(&rwad,start,size,name); } } } /* ** SS_START ** sprites ** SS_END */ if(select&BSPRITE) { start=size=0; if(TXTseekSection(TXT,"SPRITES")) { Phase("CM75", "Making sprites"); FoundOne=FALSE; while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE)==TRUE) { /* first sprite seen? */ if((Repeat!=TRUE)||(FoundOne!=TRUE)) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); if(FoundOne!=TRUE) { if(type==IWAD) WADRdirAddEntry(&rwad,start,0L,"S_START"); else WADRdirAddEntry(&rwad,start,0L,"SS_START"); } FoundOne=TRUE; CMPOloadPic(&size,&rwad,file,DataDir,"SPRITES",name, filenam,PSPRIT,X,Y); } WADRdirAddEntry(&rwad,start,size,name); } if(FoundOne==TRUE) { WADRalign4(&rwad); start=WADRposition(&rwad); if((type==IWAD)||(George==TRUE)) WADRdirAddEntry(&rwad,start,0L,"S_END"); else WADRdirAddEntry(&rwad,start,0L,"SS_END"); } } } /* ** Try to load patches ** even if no new textures (old patches could be redefined) */ /* write new patches in PWAD*/ /* read the name of the new textures and insert them*/ /* between P_START and P_END for future completion*/ if(select&BPATCH) { FoundOne=FALSE; /* ** First look for patches in [PATCHES] */ start=size=0; if(TXTseekSection(TXT,"PATCHES")) { Phase("CM80", "Making patches"); while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE)==TRUE) { if((Repeat!=TRUE)||(FoundOne!=TRUE)) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); if(FoundOne==FALSE) { if(type==IWAD) { WADRdirAddEntry(&rwad,start,0L,"P_START"); WADRdirAddEntry(&rwad,start,0L,"P1_START"); } else { WADRdirAddEntry(&rwad,start,0L,"PP_START"); } } FoundOne=TRUE; CMPOloadPic(&size,&rwad,file,DataDir,"PATCHES",name, filenam,PPATCH,X,Y); } WADRdirAddEntry(&rwad,start,size,name); } } /* ** Check if all the needed patches are defined. */ nbPatchs=PNMgetNbOfPatch(); for(p=0;p=0) { Output("Reusing DOOM entry %s as patch\n", lump_name (name)); } /*search in current PWAD*/ else if(WADRfindEntry(&rwad,name)<0) { /*PATCH not found in current WAD, load automatically **from the PATCH directory */ WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); Picture=CMPOloadPic(&size,&rwad,file,DataDir,"PATCHES",name, filenam,PPATCH,INVALIDINT,INVALIDINT); if(Picture!=PICNONE) { if(FoundOne==FALSE) { Phase("CM82", "Making patches"); if(type==IWAD) { WADRdirAddEntry(&rwad,start,0L,"P_START"); WADRdirAddEntry(&rwad,start,0L,"P1_START"); } else WADRdirAddEntry(&rwad,start,0L,"PP_START"); } FoundOne=TRUE; WADRdirAddEntry(&rwad,start,size,name); } } } if(FoundOne==TRUE) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); if(type==IWAD) { WADRdirAddEntry(&rwad,start,0L,"P1_END"); WADRdirAddEntry(&rwad,start,0L,"P2_START"); WADRdirAddEntry(&rwad,start,0L,"P2_END"); WADRdirAddEntry(&rwad,start,0L,"P3_START"); WADRdirAddEntry(&rwad,start,0L,"P3_END"); WADRdirAddEntry(&rwad,start,0L,"P_END"); } else WADRdirAddEntry(&rwad,start,0L,"PP_END"); } } /* ** clear off Pnames */ if(select&(BTEXTUR|BPATCH)) { PNMfree(); } /* FF_START ** Flats ** F_END AYM 1998-12-22 (was FF_END) */ if(select&BFLAT) { if(TXTseekSection(TXT,"FLATS")) { Phase("CM85", "Making flats"); FoundOne=FALSE; while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE) { if((Repeat!=TRUE)||(FoundOne!=TRUE)) { WADRalign4(&rwad); /*align entry on Int32 word*/ start=WADRposition(&rwad); if(FoundOne==FALSE) { if(type==IWAD) { WADRdirAddEntry(&rwad,start,0L,"F_START"); WADRdirAddEntry(&rwad,start,0L,"F1_START"); } else WADRdirAddEntry(&rwad,start,0L,"FF_START"); } FoundOne=TRUE; CMPOloadPic(&size,&rwad,file,DataDir,"FLATS",name, filenam,PFLAT,INVALIDINT,INVALIDINT); } WADRdirAddEntry(&rwad,start,size,name); } if(FoundOne==TRUE) { start=WADRposition(&rwad); if(type==IWAD) { WADRdirAddEntry(&rwad,start,0L,"F1_END"); WADRdirAddEntry(&rwad,start,0L,"F2_START"); WADRdirAddEntry(&rwad,start,0L,"F2_END"); WADRdirAddEntry(&rwad,start,0L,"F3_START"); WADRdirAddEntry(&rwad,start,0L,"F3_END"); WADRdirAddEntry(&rwad,start,0L,"F_END"); } else WADRdirAddEntry(&rwad,start,0L,"F_END"); /* AYM 1998-12-22 */ } } } /* ** exit from graphic */ if(select&(BGRAPHIC|BSPRITE|BPATCH|BFLAT)) COLfree(); /* ** iwad not needed anymore */ WADRclose(&iwad); /* ** the end */ TXTcloseR(TXT); WADRwriteDir(&rwad, 1); /* write the WAD directory */ ProgErrorCancel(); WADRclose(&rwad); /*add some junk at end of wad file, for DEU 5.21*/ if(type==PWAD) AddSomeJunk(PWADname); } /***************** Hack the IWAD *********************/ extern Int16 HowMuchJunk; static char Junk[] ="This junk is here for DEU 5.21. I am repeating myself anyway... "; static void AddSomeJunk(const char *file) { FILE *out;Int16 n; out=fopen(file,FOPEN_AB); /*open R/W at the end*/ if(out==NULL) ProgError("CM97", "%s: %s", fname (file), strerror (errno)); for(n=0;n #include #include #include "tools.h" #include "log.h" #include "mkwad.h" #include "merge.h" #include "extract.h" #include "wadio.h" #include "picture.h" #include "usedidx.h" /*compile only for DeuTex*/ #if (defined DeuTex)||(defined DeuSF) /* ** global variables for commands */ char file[128]; /* general use file name*/ static WADTYPE Type; /*IWAD type*/ static NTRYB Select; static const char *DataDir=NULL; static const char *DoomDir=NULL; static char MainWAD[128]; /* name of the main wad file */ #if defined DeuTex static char WadInf[128]; /* name of the wadinfo file */ static Bool WadInfOk; Int16 HowMuchJunk; /* junk to add*/ static IMGTYPE Picture; /* save as PPM, BMP or GIF ? */ static SNDTYPE Sound; /* save as WAV, VOC or AU ? */ static Bool fullSND; static Bool WSafe; static Bool George; #endif /*DeuTex*/ char trnR,trnG,trnB; picture_format_t picture_format = PF_NORMAL; texture_format_t input_texture_format = TF_NORMAL; texture_format_t output_texture_format = TF_NORMAL; texture_lump_t texture_lump = TL_NORMAL; rate_policy_t rate_policy = RP_WARN; clobber_t clobber = CLOBBER_NO; const char *debug_ident = NULL; int old_music_ident_method = 0; const char *palette_lump = "PLAYPAL"; #if defined DeuTex const char *logfile = "deutex.log"; #elif defined DeuSF const char *logfile = "deusf.log"; #endif static char anon[1] = { '\0' }; typedef void (*comfun_t) (int argc, const char *argv[]); static void opt_widths (); static int is_prefix (const char *s1, const char *s2); static void call_opt (comfun_t func, ...); /* ** commands */ void COMhelp (int argc, const char *argv[]); void COMvers (int argc, const char *argv[]); void COMmanopt (int argc, const char *argv[]); void COMformat (int argc, const char *argv[]); void COMipf (int argc, const char *argv[]); void COMtf (int argc, const char *argv[]); void COMitl (int argc, const char *argv[]); /* ** WinTex comand line replaces ** -out ** -v3 ** -doom doom directory ** -dir data directory ** -sel select byte ** -colRrGgBb red = (R-'A')*16+(r-'A') */ #if defined DeuTex void COMwintxn(int argc, const char *argv[]) { const char *num; PrintInit(TRUE); /*-out*/ PrintVerbosity(3); /*-v3*/ DoomDir=argv[1]; /*doom*/ DataDir=argv[2]; /*data*/ MakeFileName(WadInf,DataDir,"","",argv[3],"TXT"); WadInfOk=TRUE; Select|= atoi(argv[4]); /*select*/ num = argv[5]; /*colour*/ if(strlen(num)<6) ProgError("AA24", "Invalid colour \"%.128s\"", num); trnR= (((num[0]&0xF)<<4)+(num[1]&0xF))&0xFF; trnG= (((num[2]&0xF)<<4)+(num[3]&0xF))&0xFF; trnB= (((num[4]&0xF)<<4)+(num[5]&0xF))&0xFF; Info("AA26", "Transparent colour is R=%d G=%d B=%d", ((int)trnR&0xFF),((int)trnG&0xFF),((int)trnB&0xFF)); (void)argc; } void COMwintxm(int argc, const char *argv[]) { PrintInit(TRUE); /*-out*/ PrintVerbosity(3); /*-v3*/ DoomDir=argv[1]; /*doom*/ DataDir="."; Select|= atoi(argv[2]); /*select*/ trnR= 0;trnG= 255;trnB= 255; (void)argc; } #endif /*DeuTex*/ void COMwintex(int argc, const char *argv[]) { PrintInit(TRUE); /*-out*/ PrintVerbosity(3); /*-v3*/ DoomDir=NULL; strncpy(MainWAD,argv[1],128);/*main*/ DataDir="."; Select|= BALL; /*select*/ trnR= 0;trnG= 255;trnB= 255; (void)argc; } void COMverbose(int argc, const char *argv[]) { PrintVerbosity(argv[0][2]-'0'); Info("AA10", "Verbosity level is %c",argv[0][2]); (void)argc; } void COMlog(int argc, const char *argv[]) { logfile = argv[1]; } void COMdoom(int argc, const char *argv[]) { DoomDir=argv[1]; Info("AA15", "Main directory: %s",DoomDir); (void)argc; } #ifdef DeuTex void COMdoom02(int argc, const char *argv[]) { call_opt (COMdoom, anon, argv[1], NULL); call_opt (COMipf, anon, "alpha", NULL); call_opt (COMtf, "tf", "none", NULL); call_opt (COMitl, anon, "none", NULL); (void)argc; } void COMdoom04(int argc, const char *argv[]) { call_opt (COMdoom, anon, argv[1], NULL); call_opt (COMipf, anon, "alpha", NULL); call_opt (COMtf, "tf", "nameless", NULL); call_opt (COMitl, anon, "textures", NULL); (void)argc; } void COMdoom05(int argc, const char *argv[]) { call_opt (COMdoom, anon, argv[1], NULL); call_opt (COMipf, anon, "alpha", NULL); call_opt (COMitl, anon, "textures", NULL); (void)argc; } void COMdoompr(int argc, const char *argv[]) { call_opt (COMdoom, anon, argv[1], NULL); call_opt (COMipf, anon, "pr", NULL); (void)argc; } #endif void COMstrife(int argc, const char *argv[]) { call_opt (COMdoom, anon, argv[1], NULL); call_opt (COMtf, "tf", "strife11", NULL); (void)argc; } void COMmain(int argc, const char *argv[]) { DoomDir=NULL; strncpy(MainWAD,argv[1],128); Info("AA16", "Main IWAD file: %s",MainWAD); (void)argc; } void COMwadir(int argc, const char *argv[]) { XTRlistDir(MainWAD,((argc<2)? NULL: argv[1]),Select); } void COMadd(int argc, const char *argv[]) { ADDallSpriteFloor(argv[2],MainWAD,argv[1],Select); (void)argc; } void COMapp(int argc, const char *argv[]) { ADDappendSpriteFloor(MainWAD,argv[1],Select); (void)argc; } void COMapps(int argc, const char *argv[]) { Select= (BALL) & (~BFLAT); /*no flats*/ ADDappendSpriteFloor(MainWAD,argv[1],Select); (void)argc; } void COMappf(int argc, const char *argv[]) { Select= (BALL) & (~BSPRITE); /*no sprites*/ ADDappendSpriteFloor(MainWAD,argv[1],Select); (void)argc; } void COMjoin(int argc, const char *argv[]) { ADDjoinWads(MainWAD,argv[1],argv[2],Select); (void)argc; } void COMmerge(int argc, const char *argv[]) { Select = BALL; PSTmergeWAD(MainWAD,argv[1],Select); (void)argc; } void COMrestor(int argc, const char *argv[]) { HDRrestoreWAD((argc>=2)? argv[1]:MainWAD); } #if defined DeuSF /* ** Selections */ void COMsprit(int argc, const char *argv[]) { Select&= ~BFLAT; Info("AA60", "Select sprites"); (void)argc;(void)argv; } void COMflat(int argc, const char *argv[]) { Select&= ~BSPRITE; Info("AA61", "Select flats"); (void)argc;(void)argv; } #endif /*DeuSF*/ #if defined DeuTex /* ** Selections */ void COMsprit(int argc, const char *argv[]) { Select|=BSPRITE; Info("AA62", "Select sprites"); (void)argc;(void)argv; } void COMflat(int argc, const char *argv[]) { Select|=BFLAT; Info("AA63", "Select flats"); (void)argc;(void)argv; } void COMlevel(int argc, const char *argv[]) { Select|=BLEVEL; Info("AA64", "Select levels"); (void)argc;(void)argv; } void COMlump(int argc, const char *argv[]) { Select|=BLUMP; Info("AA65", "Select lumps"); (void)argc;(void)argv; } void COMtextur(int argc, const char *argv[]) { Select|=BTEXTUR; Info("AA66", "Select textures"); (void)argc;(void)argv; } void COMpatch(int argc, const char *argv[]) { Select|=BPATCH; Info("AA67", "Select patches"); (void)argc;(void)argv; } void COMsound(int argc, const char *argv[]) { Select|=BSOUND; Info("AA68", "Select sounds"); (void)argc;(void)argv; } void COMmusic(int argc, const char *argv[]) { Select|=BMUSIC; Info("AA69", "Select musics"); (void)argc;(void)argv; } void COMgraphic(int argc, const char *argv[]) { Select|=BGRAPHIC; Info("AA70", "Select graphics"); (void)argc;(void)argv; } void COMsneas(int argc, const char *argv[]) { Select|=BSNEA; Info("AA71", "Select sneas"); (void)argc;(void)argv; } void COMsneaps(int argc, const char *argv[]) { Select|=BSNEAP; Info("AA72", "Select sneaps"); (void)argc;(void)argv; } void COMsneats(int argc, const char *argv[]) { Select|=BSNEAT; Info("AA73", "Select sneats"); (void)argc;(void)argv; } void COMscripts(int argc, const char *argv[]) { Select|=BSCRIPT; Info("AA74", "Select scripts"); (void)argc;(void)argv; } void COMgeorge(int argc, const char *argv[]) { George=TRUE; Info("AA32", "Using S_END for sprites"); (void)argc;(void)argv; } void PicDebug(char *file, const char *DataDir, const char *name); void COMdebug(int argc, const char *argv[]) { #include "color.h" static struct WADINFO iwad; Int16 pnm; char *Colors; Int32 Pnamsz=0; iwad.ok=0; WADRopenR(&iwad,MainWAD); pnm=WADRfindEntry(&iwad,palette_lump); if(pnm<0) ProgError("GD04", "Can't find %s in Main WAD", lump_name (palette_lump)); Colors=WADRreadEntry(&iwad,pnm,&Pnamsz); COLinit(trnR,trnG,trnB,Colors,(Int16)Pnamsz, iwad.filename, palette_lump); Free(Colors); WADRclose(&iwad); PicDebug(file,DataDir,(argc<2)? "test":argv[1]); COLfree(); (void)argc;(void)argv; } void COMdi (int argc, const char *argv[]) { Info("ID01", "Debugging identification of entry %s", lump_name (argv[1])); debug_ident = argv[1]; (void)argc; } void COMmusid (int argc, const char *argv[]) { Info ("AA19", "Using old music identification method"); old_music_ident_method = 1; (void)argc; (void)argv; } void COMdeu(int argc, const char *argv[]) { HowMuchJunk=MAXJUNK64; Info("AA33", "Will add 64 kB of junk at end of wad for DEU 5.21 compatibility"); (void)argc;(void)argv; } void COMdir(int argc, const char *argv[]) { DataDir=argv[1]; Info("AA22", "Files will be saved in directory %s",DataDir); (void)argc; } void COMfullsnd(int argc, const char *argv[]) { fullSND=TRUE; Info("AA46", "Saving sounds beyond declared length"); (void)argc;(void)argv; } void COMrate(int argc, const char *argv[]) { if (argc >= 2 && ! strcmp (argv[1], "reject")) rate_policy = RP_REJECT; else if (argc >= 2 && ! strcmp (argv[1], "force")) rate_policy = RP_FORCE; else if (argc >= 2 && ! strcmp (argv[1], "warn")) rate_policy = RP_WARN; else if (argc >= 2 && ! strcmp (argv[1], "accept")) rate_policy = RP_ACCEPT; else ProgError ("AA41", "Usage is \"-rate {reject|force|warn|accept}\""); Info("AA42", "Sample rate policy is \"%s\"", argv[1]); (void)argc; } void COMstroy (int argc, const char *argv[]) { WSafe = FALSE; Info ("AA28", "Overwrite existing files"); (void) argc; (void) argv; } void COMgif (int argc, const char *argv[]) { Picture = PICGIF; Info ("AA50", "Saving pictures as GIF (.gif)"); (void) argc; (void) argv; } void COMbmp (int argc, const char *argv[]) { Picture = PICBMP; Info ("AA51", "Saving pictures as BMP (.bmp)"); (void) argc; (void) argv; } void COMppm (int argc, const char *argv[]) { Picture = PICPPM; Info ("AA52", "Saving pictures as rawbits PPM (P6, .ppm)"); (void) argc; (void) argv; } void COMau (int argc, const char *argv[]) { Sound = SNDAU; Info ("AA43", "Save sounds as Sun audio (.au)"); (void) argc; (void) argv; } void COMwave (int argc, const char *argv[]) { Sound = SNDWAV; Info ("AA45", "Save sounds as WAVE (.wav)"); (void) argc; (void) argv; } void COMvoc (int argc, const char *argv[]) { Sound = SNDVOC; Info ("AA44", "Save sounds as voc (.voc)"); (void) argc; (void) argv; } void COMrgb (int argc, const char *argv[]) { trnR = (char) (atoi (argv[1]) & 0xFF); trnG = (char) (atoi (argv[2]) & 0xFF); trnB = (char) (atoi (argv[3]) & 0xFF); Info ("AA21", "Transparent colour is R=%d G=%d B=%d", ((int) trnR & 0xFF), ((int) trnG & 0xFF), ((int) trnB & 0xFF)); (void) argc; } void COMle (int argc, const char *argv[]) { set_input_wad_endianness (0); set_output_wad_endianness (0); (void) argc; (void) argv; } void COMbe (int argc, const char *argv[]) { set_input_wad_endianness (1); set_output_wad_endianness (1); (void) argc; (void) argv; } void COMile (int argc, const char *argv[]) { set_input_wad_endianness (0); (void) argc; (void) argv; } void COMibe (int argc, const char *argv[]) { set_input_wad_endianness (1); (void) argc; (void) argv; } void COMole (int argc, const char *argv[]) { set_output_wad_endianness (0); (void) argc; (void) argv; } void COMobe (int argc, const char *argv[]) { set_output_wad_endianness (1); (void) argc; (void) argv; } void COMipf (int argc, const char *argv[]) { if (argc >= 2 && ! strcmp (argv[1], "alpha")) picture_format = PF_ALPHA; else if (argc >= 2 && ! strcmp (argv[1], "normal")) picture_format = PF_NORMAL; else if (argc >= 2 && ! strcmp (argv[1], "pr")) picture_format = PF_PR; else if (argc >= 2 && ! strcmp (argv[1], "rott")) picture_format = PF_ROTT; else ProgError ("PI01", "Usage is \"-ipf {alpha|normal|pr|rott}\""); Info ("PI02", "Input picture format is \"%s\"", argv[1]); } #endif /* #ifdef DeuTex */ void COMtf (int argc, const char *argv[]) { int set_in = 0; int set_out = 0; if (! strcmp (argv[0], "itf")) set_in = 1; else if (! strcmp (argv[0], "otf")) set_out = 1; else if (! strcmp (argv[0], "tf")) { set_in = 1; set_out = 1; } else Bug ("AA90", "Invalid argv[0] \"%.32s\"", argv[0]); if (argc >= 2 && ! strcmp (argv[1], "nameless")) { if (set_in) input_texture_format = TF_NAMELESS; if (set_out) output_texture_format = TF_NAMELESS; } else if (argc >= 2 && ! strcmp (argv[1], "none")) { if (set_in) input_texture_format = TF_NONE; if (set_out) output_texture_format = TF_NONE; } else if (argc >= 2 && ! strcmp (argv[1], "normal")) { if (set_in) input_texture_format = TF_NORMAL; if (set_out) output_texture_format = TF_NORMAL; } else if (argc >= 2 && ! strcmp (argv[1], "strife11")) { if (set_in) input_texture_format = TF_STRIFE11; if (set_out) output_texture_format = TF_STRIFE11; } else ProgError ("TX04", "Usage is \"-%.32s {nameless|none|normal|strife11}\"", argv[0]); if (set_in) Info ("TX05", "Input texture format is \"%s\"", argv[1]); if (set_out) Info ("TX06", "Output texture format is \"%s\"", argv[1]); } #ifdef DeuTex void COMitl (int argc, const char *argv[]) { if (argc >= 2 && ! strcmp (argv[1], "none")) texture_lump = TL_NONE; else if (argc >= 2 && ! strcmp (argv[1], "textures")) texture_lump = TL_TEXTURES; else if (argc >= 2 && ! strcmp (argv[1], "normal")) texture_lump = TL_NORMAL; else ProgError ("TX01", "Usage is \"-itl {none|textures|normal}\""); Info ("TX02", "Input texture lump is \"%s\"", argv[1]); } /* ** Build an IWAD ** */ void COMiwad(int argc, const char *argv[]) { Type=IWAD; Info("AA31", "Building an iwad"); (void)argc;(void)argv; } /* ** Main Commands ** */ void COMmake(int argc, const char *argv[]) { const char *wadinf,*wadout; if(WadInfOk==FALSE) { MakeFileName(WadInf,DataDir,"","","WADINFO","TXT"); } if(argc<=2){wadinf=WadInf;wadout=argv[1];} else {wadinf=argv[1];wadout=argv[2];} CMPOmakePWAD(MainWAD,Type,wadout,DataDir,wadinf,Select,trnR,trnG,trnB,George); (void)argc; } void COMxtra(int argc, const char *argv[]) { const char *wadinf, *wadin; if(WadInfOk==FALSE) { MakeFileName(WadInf,DataDir,"","","WADINFO","TXT"); } if(argc<=1){wadin=MainWAD;}else{wadin=argv[1];} if(argc<=2){wadinf=WadInf;}else{wadinf=argv[2];} XTRextractWAD (MainWAD, DataDir, wadin, wadinf, Picture, Sound, fullSND, Select, trnR, trnG, trnB, WSafe, NULL); } void COMget(int argc, const char *argv[]) { XTRgetEntry(MainWAD,DataDir,((argc<3)? MainWAD: argv[2]),argv[1],Picture,Sound,fullSND,trnR,trnG,trnB); } void COMpackNorm(int argc, const char *argv[]) { XTRcompakWAD(DataDir,(argc>1)? argv[1]: MainWAD,(argc>2)? argv[2]:NULL,FALSE); } void COMpackGfx(int argc, const char *argv[]) { XTRcompakWAD(DataDir,(argc>1)? argv[1]: MainWAD,(argc>2)? argv[2]:NULL,TRUE); } void COMvoid(int argc, const char *argv[]) { XTRvoidSpacesInWAD(argv[1]); (void)argc; } void COMusedtex(int argc, const char *argv[]) { XTRtextureUsed((argc>1)? argv[1]: MainWAD); } void COMusedidx(int argc, const char *argv[]) { const char *wadinf, *wadin; cusage_t *cusage = NULL; if(WadInfOk==FALSE) { MakeFileName(WadInf,DataDir,"","","WADINFO","TXT"); /* Not used anyway */ } if(argc<=1){wadin=MainWAD;}else{wadin=argv[1];} if(argc<=2){wadinf=WadInf;}else{wadinf=argv[2];} cusage = Malloc (sizeof *cusage); { int n; for (n = 0; n < NCOLOURS; n++) { cusage->uses[n] = 0; cusage->nlumps[n] = 0; cusage->where_first[n][0] = '\0'; } } XTRextractWAD (MainWAD, DataDir, wadin, wadinf, Picture, Sound, fullSND, Select, trnR, trnG, trnB, WSafe, cusage); Free (cusage); } #endif /*DeuTex*/ void COMcheck(int argc, const char *argv[]) { XTRstructureTest(MainWAD,argv[1]); (void)argc; } enum { OC_MASK = 0xc0, OC_SEC = 0x00, OC_OPT = 0x40, OC_MOD = 0x80, OC_END = 0xc0, }; #define PASS(comtype) ((comtype) & 0x1f) typedef unsigned char COMTYPE; #define SEC OC_SEC /* Section (used by --help/-man) */ #define CM0 OC_MOD + 0 /* Modal (no banner, no log, no iwad) */ /* -------- Banner is printed -------- */ #define CM1 OC_MOD + 1 /* Modal (banner, no log, no iwad) */ #define OP1 OC_OPT + 2 /* Opt (-log) */ /* -------- Log file is opened -------- */ #define OP2 OC_OPT + 3 /* Opt (banner, log) */ #define CM3 OC_MOD + 0x04 /* Modal (banner, log, no iwad) */ #define CM4 OC_MOD + 0x24 /* Modal (banner, log, iwad required) */ #define END OC_END typedef struct { COMTYPE type; char argc; char *com; comfun_t exec; char *use; char *help; } comdef_t; /* FIXME should be at the top of the file but we need comdef_t */ static const comdef_t *parse_argv (int *argc, const char ***argv, int pass); static comdef_t Com[]= { {SEC,0,NULL, NULL, NULL, "Modal options not requiring an iwad"}, {CM1,0,"?", COMhelp, NULL, "same as \1--help\3"}, {CM1,0,"h", COMhelp, NULL, "same as \1--help\3"}, {CM1,0,"help", COMhelp, NULL, "same as \1--help\3"}, {CM1,0,"-help", COMhelp, NULL, "print list of options"}, #ifdef DeuTex {CM0,0,"man", COMmanopt, NULL, "print list of options in troff -man format"}, #endif {CM0,0,"syntax", COMformat, NULL, "print the syntax of wad creation directives"}, #ifdef DeuTex {CM3,1,"unused", COMvoid, "", "find unused spaces in a wad"}, #endif /*DeuTex*/ {CM0,0,"-version", COMvers, NULL, "print version number and exit successfully"}, {SEC,0,NULL, NULL, NULL, "Modal options requiring an iwad"}, {CM4,2,"add", COMadd, " ", "copy sp & fl of iwad and \2in.wad\3 to \2out.wad\3"}, {CM4,1,"af", COMappf, "", "append all floors/ceilings to the wad"}, {CM4,1,"append", COMapp, "", "add sprites & flats of iwad to \2io.wad\3"}, {CM4,1,"as", COMapps, "", "append all sprites to the wad"}, #ifdef DeuTex {CM4,1,"build", COMmake, "[] ", "make a pwad"}, #endif {CM4,1,"check", COMcheck, "", "check the textures"}, #ifdef DeuTex {CM4,1,"create", COMmake, "[] ", "same as \1-build\3"}, {CM4,0,"debug", COMdebug, "[]", "debug colour conversion"}, {CM4,0,"extract", COMxtra, "[ []]","same as \1-xtract\3"}, {CM4,1,"get", COMget, " []", "get a wad entry from main wad or \2in.wad\3"}, #endif {CM4,2,"join", COMjoin, " ","append sprites & flats of Doom to a pwad"}, #ifdef DeuTex {CM4,1,"make", COMmake, "[] ", "same as \1-build\3"}, #endif {CM4,1,"merge", COMmerge, "", "merge doom.wad and a pwad"}, #ifdef DeuTex {CM4,1,"pkgfx", COMpackGfx, "[ []]","detect identical graphics"}, {CM4,1,"pknormal", COMpackNorm,"[ []]","detect identical normal"}, #endif {CM4,0,"restore", COMrestor, NULL, "restore doom.wad and the pwad"}, {CM4,1,"test", COMcheck, "", "same as \1-check\3"}, #ifdef DeuTex {CM4,0,"usedidx", COMusedidx, "[]", "colour index usage statistics"}, {CM4,0,"usedtex", COMusedtex, "[]", "list textures used in all levels"}, #endif /*DeuTex*/ {CM4,0,"wadir", COMwadir, "[]", "list and identify entries in a wad"}, #ifdef DeuTex {CM4,0,"xtract", COMxtra, "[ []]","extract some/all entries from a wad"}, #endif /*DeuTex*/ {SEC,0,NULL, NULL, NULL, "General options"}, #ifdef DeuTex {OP2,0,"overwrite",COMstroy, NULL, "overwrite all"}, #endif #ifdef DeuTex {OP2,1,"dir", COMdir, "", "extraction directory (default \1.\3)"}, #endif {SEC,0,NULL, NULL, NULL, "Iwad"}, {OP2,1,"doom", COMdoom, "", "path to Doom iwad"}, {OP2,1,"doom2", COMdoom, "", "path to Doom II iwad"}, #ifdef DeuTex {OP2,1,"doom02", COMdoom02, "", "path to Doom alpha 0.2 iwad"}, {OP2,1,"doom04", COMdoom04, "", "path to Doom alpha 0.4 iwad"}, {OP2,1,"doom05", COMdoom05, "", "path to Doom alpha 0.5 iwad"}, {OP2,1,"doompr", COMdoompr, "", "path to Doom PR pre-beta iwad"}, #endif {OP2,1,"heretic", COMdoom, "", "path to Heretic iwad"}, {OP2,1,"hexen", COMdoom, "", "path to Hexen iwad"}, #ifdef DeuSF {OP2,1,"main", COMmain, NULL, "pathname of iwad"}, #endif {OP2,1,"strife", COMstrife, "", "path to Strife iwad"}, {OP2,1,"strife10", COMdoom, "", "path to Strife 1.0 iwad"}, #ifdef DeuTex {SEC,0,NULL, NULL, NULL, "Wad options"}, {OP2,0,"be", COMbe, NULL, "assume all wads are big endian (default LE)"}, {OP2,0,"deu", COMdeu, NULL, "add 64k of junk for DEU 5.21 compatibility"}, {OP2,0,"george", COMgeorge, NULL, "same as \1-s_end\3"}, {OP2,0,"ibe", COMibe, NULL, "input wads are big endian (default LE)"}, {OP2,0,"ile", COMile, NULL, "input wads are little endian (default)"}, {OP2,1,"ipf", COMipf, "", "picture format (\1alpha\3, *\1normal\3, \1pr\3, \1rott\3)"}, {OP2,1,"itf", COMtf, "", "input texture format (\1nameless\3, \1none\3, *\1normal\3, \1strife11\3)"}, {OP2,1,"itl", COMitl, "", "texture lump (\1none\3, *\1normal\3, \1textures\3)"}, {OP2,0,"iwad", COMiwad, NULL, "compose iwad, not pwad"}, {OP2,0,"le", COMle, NULL, "assume all wads are little endian (default)"}, {OP2,0,"musid", COMmusid, NULL, "use old music identification method"}, {OP2,0,"obe", COMobe, NULL, "create big endian wads (default LE)"}, {OP2,0,"ole", COMole, NULL, "create little endian wads (default)"}, {OP2,1,"otf", COMtf, "", "output texture format (\1nameless\3, \1none\3, *\1normal\3, \1strife11\3)"}, /*by request from George Hamlin*/ {OP2,0,"s_end", COMgeorge, NULL, "use \1S_END\3 for sprites, not \1SS_END\3"}, {OP2,1,"tf", COMtf, "", "texture format (\1nameless\3, \1none\3, *\1normal\3, \1strife11\3)"}, #endif /*DeuTex*/ {SEC,0,NULL, NULL, NULL, "Lump selection"}, {OP2,0,"flats", COMflat, NULL, "select flats"}, #ifdef DeuTex {OP2,0,"graphics", COMgraphic, NULL, "select graphics"}, {OP2,0,"levels", COMlevel, NULL, "select levels"}, {OP2,0,"lumps", COMlump, NULL, "select lumps"}, {OP2,0,"musics", COMmusic, NULL, "select musics"}, {OP2,0,"patches", COMpatch, NULL, "select patches"}, {OP2,0,"scripts", COMscripts, NULL, "select Strife scripts"}, {OP2,0,"sneas", COMsneas, NULL, "select sneas (sneaps and sneats)"}, {OP2,0,"sneaps", COMsneaps, NULL, "select sneaps"}, {OP2,0,"sneats", COMsneats, NULL, "select sneats"}, {OP2,0,"sounds", COMsound, NULL, "select sounds"}, #endif /*DeuTex*/ {OP2,0,"sprites", COMsprit, NULL, "select sprites"}, #ifdef DeuTex {OP2,0,"textures", COMtextur, NULL, "select textures"}, #endif /*DeuTex*/ #ifdef DeuTex {SEC,0,NULL, NULL, NULL, "Graphics"}, {OP2,0,"bmp", COMbmp, NULL, "save pictures as BMP (\1.bmp\3)"}, {OP2,0,"gif", COMgif, NULL, "save pictures as GIF (\1.gif\3)"}, {OP2,0,"ppm", COMppm, NULL, "save pictures as rawbits PPM (P6, \1.ppm\3)"}, {OP2,3,"rgb", COMrgb, " ", "specify the transparent colour (default 0 47 47)"}, #endif #ifdef DeuTex {SEC,0,NULL, NULL, NULL, "Sound"}, {OP2,0,"au", COMau, NULL, "save sounds as Sun audio (\1.au\3)"}, {OP2,0,"fullsnd", COMfullsnd, NULL, "save sounds beyond declared length"}, {OP2,1,"rate", COMrate, "", "policy for != 11025 Hz (\1reject\3, \1force\3, *\1warn\3, \1accept\3)"}, {OP2,0,"voc", COMvoc, NULL, "save sounds as voc (\1.voc\3)"}, {OP2,0,"wav", COMwave, NULL, "save sounds as WAVE (\1.wav\3)"}, #endif {SEC,0,NULL, NULL, NULL, "Reporting"}, #ifdef DeuTex {OP2,1,"di", COMdi, "", "debug identification of entry"}, {OP1,1,"log", COMlog, "", "name of log file (default \1deutex.log\3)"}, #elif defined DeuSF {OP1,1,"log", COMlog, "", "name of log file (default \1deusf.log\3)"}, #endif {OP2,0,"v0", COMverbose, NULL, "set verbosity level to 0"}, {OP2,0,"v1", COMverbose, NULL, "set verbosity level to 1"}, {OP2,0,"v2", COMverbose, NULL, "set verbosity level to 2 (default)"}, {OP2,0,"v3", COMverbose, NULL, "set verbosity level to 3"}, {OP2,0,"v4", COMverbose, NULL, "set verbosity level to 4"}, {OP2,0,"v5", COMverbose, NULL, "set verbosity level to 5"}, {SEC,0,NULL, NULL, NULL, "WinTex-related options"}, #ifdef DeuTex {OP2,5,"win", COMwintxn, " ", "WinTex shortcut"}, #endif /*DeuTex*/ {OP2,1,"wtx", COMwintex, "", "WinTex shortcut"}, {END,0,"", COMhelp, NULL, ""} }; int main (int argc, char *argv_non_const[]) { /* Create argv[] identical to argv_[] but of type (const char **). We do this to avoid the warnings about initialising a (const char **) with a (char **). */ const char **argv = malloc (argc * sizeof *argv); if (argv == NULL) ProgError ("MM69", "Out of memory (%d)", argc); { size_t n; for (n = 0; n < argc; n++) argv[n] = argv_non_const[n]; } /* Do a first pass through argv to process the options where you don't want the banners (-version, -man) */ { int c = argc - 1; const char **v = argv + 1; const comdef_t *d = parse_argv (&c, &v, 0); if (d != NULL) { d->exec (c, v); exit (0); } } #ifdef DT_ALPHA printf ( "+-----------------------------------------------------------+\n" "| THIS IS ALPHA SOFTWARE. DON'T EXPECT IT TO COMPILE OR |\n" "| RUN SMOOTHLY. DON'T EXPECT THE DOCUMENTATION TO BE |\n" "| ACCURATE OR UP TO DATE. THERE MIGHT BE SERIOUS BUGS. |\n" "| MAKE BACKUP COPIES OF YOUR DATA. |\n" "+-----------------------------------------------------------+\n\n"); #endif #ifdef DT_PRIVATE printf ( "\t+------------------------------------+\n" "\t| THIS RELEASE OF DEUTEX IS NOT |\n" "\t| INTENDED FOR PUBLIC CONSUMPTION. |\n" "\t| DO NOT FURTHER DISTRIBUTE. |\n" "\t+------------------------------------+\n\n"); #endif /* Sanity checks */ check_types (); /* ** default parameters */ #if defined DeuTex WadInfOk=FALSE; George=FALSE; #if DT_OS == 'd' Picture = PICBMP; Sound = SNDWAV; #elif DT_OS == 'o' Picture = PICBMP; Sound = SNDWAV; #else /*Unix*/ Picture = PICPPM; Sound = SNDAU; #endif trnR=0;trnG=47;trnB=47; fullSND = FALSE; WSafe = TRUE; HowMuchJunk= 0; Select = 0; #endif /*DeuTex*/ #if defined DeuSF Select = BALL; #endif /*DeuSF*/ Type = PWAD; ProgErrorCancel();/*no error handler defined*/ #if defined __OS2__ || defined (__GNUC__) /*setbuf(stdout,(char *)NULL);*/ setvbuf(stdout,NULL,_IOLBF,BUFSIZ); #endif /*OS2*/ /* ** print on screen or file? */ PrintInit(FALSE); PrintVerbosity(2); /* Do a second pass through argv to catch options like --help that shouldn't cause the creation of a log file. */ { int c = argc - 1; const char **v = argv + 1; const comdef_t *d = parse_argv (&c, &v, 1); if (d != NULL) { d->exec (c, v); exit (0); } } /* At this point, we have either (1) no modal option or (2) a modal option which requires writing to log. Make a third pass through argv to find out. */ { int c = argc - 1; const char **v = argv + 1; const comdef_t *d = parse_argv (&c, &v, 4); if (d == NULL) ProgError ("AA96", "No command given"); /* We now know we need to create a log. Do a pass through argv to catch -log. */ { int c = argc - 1; const char **v = argv + 1; parse_argv (&c, &v, 2); } /* Create the log file. From now on, all calls to Detail, Phase, Info, Warning, nf_err, ProgError and Bug will update the log. FIXME Output() will too and I'm not sure that's right. */ lopen (); /* Write the header of the log file. */ /* FIXME use Info */ lprintf ("%c AA00 %s %s\n", MSGCLASS_INFO, DEUTEXNAME, deutex_version); { int n; for (n = 1; n < argc; n++) /* FIXME use Info() */ lprintf ("%c AA05 argv[%d] \"%s\"\n", MSGCLASS_INFO, n, argv[n]); } /* Default iwad directory */ DataDir = "."; DoomDir = getenv ("DOOMWADDIR"); if (DoomDir == NULL) DoomDir = "."; else Phase ("AA17", "Doom directory is %.128s", DoomDir); /* Honour the non-modal options */ { int c = argc - 1; const char **v = argv + 1; parse_argv (&c, &v, 3); } /* If the modal option requires an iwad, find it. */ if (d->type & 0x20) { static const char *wads[] = { "doom", /* Doom, Ultimate Doom, Doom alpha */ "doom2", /* Doom II */ "plutonia", /* Final Doom */ "tnt", /* Final Doom */ "heretic", /* Heretic */ "hexen", /* Hexen */ "strife1", /* Strife */ "doompres", /* Doom Press Release pre-beta */ "doom1", /* Doom shareware */ "heretic1", /* Heretic demo */ "strife0", /* Strife demo */ NULL }; int gotit = 0; const char **w; for (w = wads; *w != NULL; w++) { if (MakeFileName (MainWAD, ".", "", "", *w, "wad") == TRUE) { gotit = 1; break; } } if (! gotit) { for (w = wads; *w != NULL; w++) { if (MakeFileName (MainWAD, DoomDir, "", "", *w, "wad") == TRUE) { gotit = 1; break; } } } if (! gotit) ProgError ("AA18", "Can't find any of doom.wad, doom2.wad, doompres.wad," " heretic.wad, hexen.wad, strife1.wad"); #if 0 if( MakeFileName(MainWAD,DoomDir,"","","doompres","wad")!=TRUE && MakeFileName(MainWAD,DoomDir,"","","doom", "wad")!=TRUE && MakeFileName(MainWAD,DoomDir,"","","doom2", "wad")!=TRUE && MakeFileName(MainWAD,DoomDir,"","","heretic", "wad")!=TRUE && MakeFileName(MainWAD,DoomDir,"","","hexen", "wad")!=TRUE && MakeFileName(MainWAD,DoomDir,"","","strife1", "wad")!=TRUE && MakeFileName(MainWAD,".", "","","doompres","wad")!=TRUE && MakeFileName(MainWAD,".", "","","doom", "wad")!=TRUE && MakeFileName(MainWAD,".", "","","doom2", "wad")!=TRUE && MakeFileName(MainWAD,".", "","","heretic", "wad")!=TRUE && MakeFileName(MainWAD,".", "","","hexen", "wad")!=TRUE && MakeFileName(MainWAD,".", "","","strife1", "wad")!=TRUE) ; #endif } #if defined DeuTex if (! (Select & BALL)) Select = BALL; if (Picture == PICGIF) Warning ("GX10", "GIF support may go away in the future"); #endif /*DeuTex*/ if (ROTT) palette_lump = "PAL"; d->exec (c, v); } Info ("AA99", "Normal exit"); return 0; } /* * parse_argv - parse the command line * * Only the non-modal options whose group matches the * argument are executed. * * Modal options are never executed. If their group matches , * the function returns a pointer to their definition in Com[]. * Otherwise, the function returns a null pointer. * * Upon return, *argc and *argv point one past the last argument * processed. */ static const comdef_t *parse_argv (int *argc, const char ***argv, int pass) { /* Parse the command line from left to right. Try to match the each argument against the longest possible option defined. */ while (*argc > 0) { const comdef_t *d = Com + sizeof Com / sizeof *Com - 1; const char *arg = **argv; if (*arg != '-') ProgError("AA92", "Argument \"%s\": not an option", arg); arg++; { const comdef_t *w; for (w = Com; w->type != END; w++) { int r; if ((w->type & OC_MASK) == OC_SEC) continue; r = is_prefix (arg, w->com); if (r != 0) { if (r > 1) /* Exact match. */ { d = w; goto got_it; } if (d->type != END) /* Ambiguous partial match. */ ProgError ("AA93", "\"-%s\" is ambiguous (-%s, -%s)", arg, d->com, w->com); /* Unambiguous partial match. */ d = w; } } } got_it: if (*argc - 1 < d->argc) ProgError("AA94", "Usage: -%s%s%s", d->com, d->use ? " " : "", d->use ? d->use : ""); { int class = (d->type & 0xc0); int group = (d->type & 0x1f); if (class == OC_SEC) { ; /* Can't happen */ } else if (class == OC_OPT) { if (group == pass) d->exec (*argc, *argv); } else if (class == OC_MOD) { if (group == pass) return d; else return NULL; /* Parsing ALWAYS stops at the first modal option. */ } else if (class == OC_END) { ProgError("AA95", "Invalid option \"%s\"", **argv); } else { Bug ("AA97", "Com #%d: invalid class %02Xh", (int) (d - Com), class); } } *argv += d->argc + 1; *argc -= d->argc + 1; } return NULL; /* Found no modal option for this pass number */ } /* ** Print Help */ #define TTYCOL 79 #define OPTINDENT 2 #define COLSPACING 2 void COMhelp(int argc, const char *argv[]) { const comdef_t *d; size_t width1 = 22; size_t width2 = 22; int section = 0; printf ("Help for %s:\n", DEUTEXNAME); opt_widths (); for (d = Com; d->type != END; d++) { /* Do a first pass on all the options for this section. Find out how wide the left and right columns need to be. */ if (d->type == SEC) { if (section++) putchar ('\n'); printf ("%s:\n", d->help); width1 = *((short *) &d->exec) + OPTINDENT; width2 = *((short *) &d->use); if (width1 + 1 + width2 > TTYCOL) width1 = TTYCOL - width2 - COLSPACING; } /* Now that we know how wide the left column needs to be, print all the options in this section. */ else { char buf[200]; size_t l; size_t desclen; const char *desc; sprintf (buf, "%*s-%s", OPTINDENT, "", d->com); if (d->use) { strcat (buf, " "); strcat (buf, d->use); } l = strlen (buf); desc = d->help; { const char *p; for (desclen = 0, p = desc; *p != '\0'; p++) if (*p < '\1' || *p > '\3') desclen++; } if (l > width1 || l + COLSPACING + desclen > TTYCOL) printf ("%s\n%*s", buf, (int) width1 + COLSPACING, ""); else printf ("%-*s%*s", (int) width1, buf, COLSPACING, ""); for (; *desc != '\0'; desc++) { if (*desc == '\1') ; else if (*desc == '\2') ; else if (*desc == '\3') ; else putchar (*desc); } putchar ('\n'); } } (void)argc;(void)argv; } /* * Print version and exit successfully. * All --version does. */ void COMvers (int argc, const char *argv[]) { (void) argc; (void) argv; printf ("%s %.32s\n", DEUTEXNAME, deutex_version); exit (0); } #if defined DeuTex static char *Format[] = { "* Format of PWAD creation directives *", "This format is conform to MS-Windows .INI Files.", "Sections are named [LEVELS] [LUMPS] [SOUNDS]", "[MUSICS] [TEXTURE1] [TEXTURE2] [GRAPHICS]", "[SPRITES] [PATCHES] [FLATS] [SNEAPS] [SNEATS]", "Entries have format:", "{name}= {filename} {offsetX} {offsetY}", "A '*' at the end of the definition means that the", "entry will be exactly the same as the previous one.", NULL }; #endif /*DeuTex*/ #if defined DeuSF static char *Format[] = { "To work with this progam, your PWAD must respect this format:", "- Either S_START or SS_START before the first SPRITE entry", "- Either S_END or SS_END after the last SPRITE entry", "- Either F_START or FF_START before the first FLAT entry", "- Either F_END or FF_END after the last FLAT entry", "This format has been found compatible with DMADDS 1.0.", "Warning:", "Flats declared in PWAD will be put at the end of the FLAT list.", "You can completely replace an animation of FLATs, but you cannot", "replace only part of an animation.", NULL }; #endif /*DeuSF*/ void COMformat(int argc, const char *argv[]) { int i; for(i=0;Format[i]!=NULL;i++) puts (Format[i]); (void)argc;(void)argv; } /* * COMmanopt * List options like COMhelp but in troff -man source format. */ #ifdef DeuTex static char stack[10]; static void spush (char c) { if (strlen (stack) + 1 >= sizeof stack) return; stack[strlen (stack) + 1] = '\0'; stack[strlen (stack)] = c; } #if 0 static char speektop (void) { if (! *stack) return '\0'; return stack[strlen (stack) - 1]; } #endif static char spop (void) { char c; if (! *stack) return '\0'; c = stack[strlen (stack) - 1]; stack[strlen (stack) - 1] = '\0'; return c; } static char last_font; static char troff_stack[10]; static void troff_start (void) { last_font = '\0'; *troff_stack = '\0'; } static void troff_end (void) { if (last_font) fputs ("\\fP", stdout); last_font = '\0'; } static void troff_push (char font) { if (strlen (troff_stack) + 1 >= sizeof troff_stack) return; troff_stack[strlen (troff_stack) + 1] = '\0'; troff_stack[strlen (troff_stack)] = font; } static void troff_pop (void) { if (! *troff_stack) return; troff_stack[strlen (troff_stack) - 1] = '\0'; } static char troff_tos (void) { if (! *troff_stack) return '\0'; return troff_stack[strlen (troff_stack) - 1]; } static void troff_putc (char c/*, char font*/) { if (troff_tos () && troff_tos () != last_font) { if (last_font) fputs ("\\fP", stdout); fprintf (stdout, "\\f%c", troff_tos ()); last_font = troff_tos (); } fputc (c, stdout); } static void troff_puts (const char *s/*, char font*/) { if (troff_tos () && troff_tos () != last_font) { if (last_font) fputs ("\\fP", stdout); fprintf (stdout, "\\f%c", troff_tos ()); last_font = troff_tos (); } fputs (s, stdout); } /* Number of columns guaranteed when troff formats a man page in a 80-column width TTY. This is the minimum (Solaris 10). AIX, Digital Unix, HP-UX and Irix all use more columns. */ #define MANCOLS 60 #define COLSPACING_MAN 2 void COMmanopt(int argc, const char *argv[]) { const comdef_t *d; size_t width1 = 0; size_t width2 = 0; opt_widths (); for (d = Com; d->type != END; d++) { if (d->type == SEC) { fprintf (stdout, ".SS %s\n", d->help); width1 = d->argc + COLSPACING_MAN; width2 = *((short *) &d->com) + 1; /* + 1 because of the full stop */ } else { const char *p = d->use; *stack = '\0'; troff_start (); { char buf[30]; if (width1 < 16 && width1 + width2 <= MANCOLS) sprintf (buf, ".TP %lu\n", (unsigned long) width1); else strcpy (buf, ".TP\n"); troff_puts (buf); } /* Print the option name in bold */ troff_push ('B'); troff_puts ("\\-"); troff_puts (d->com); troff_pop (); if (p) troff_putc (' '); /* Print the arguments. What's between < > is in italic, [ ] { | } are in normal roman, the rest is in bold. */ if (p) while (*p) /* Print one arg. for each iteration */ { if (isspace (*p)) troff_putc (' '); while (isspace (*p)) p++; troff_push ('B'); for (; *p && *p != ' '; p++) { if (*p == '[' || *p == '{') { spush (*p); troff_push ('R'); troff_putc (*p); troff_pop (); } else if (*p == '<') { spush (*p); troff_push ('I'); } else if (*p == ']' || *p == '}') { spop (); troff_push ('R'); troff_putc (*p); troff_pop (); } else if (*p == '>') { spop (); troff_pop (); } else if (*p == '|') { troff_push ('R'); troff_putc ('|'); troff_pop (); } else troff_putc (*p); } troff_pop (); } troff_end (); troff_putc ('\n'); /* Print the description */ { const unsigned char *p = (const unsigned char *) d->help; if (islower (*p)) { troff_putc (toupper (*p)); p++; } for (; *p != '\0'; p++) { if (*p == '\1') fputs ("\\fB", stdout); else if (*p == '\2') fputs ("\\fI", stdout); else if (*p == '\3') fputs ("\\fP", stdout); else if (*p == '-') fputs ("\\-", stdout); else fputc (*p, stdout); } fputs (".\n", stdout); } } } (void)argc;(void)argv; } #endif /* DeuTex */ /* * opt_widths - make a pass through Com and compute widths per section */ static void opt_widths () { comdef_t *d; comdef_t *current_section = NULL; size_t width1t = 0; size_t width1r = 0; size_t width2t = 0; size_t width2r = 0; for (d = Com; ; d++) { if (d->type == SEC || d->type == END) { /* Seen all the entries of a section. Set - argc = maximum roff width of the first column, - com = maximum roff width of the second column, - exec = maximum text width of the first column, - use = maximum text width of second column. */ if (current_section != NULL) { current_section->argc = (char) width1r; if (current_section->argc != width1r) current_section->argc = CHAR_MAX; /* Can't happen */ *((short *) ¤t_section->com) = (short) width2r; if (*((short *) ¤t_section->com) != width2r) *((short *) ¤t_section->com) = SHRT_MAX; /* Can't happen */ *((short *) ¤t_section->exec) = (short) width1t; if (*((short *) ¤t_section->exec) != width1t) *((short *) ¤t_section->exec) = SHRT_MAX; /* Can't happen */ *((short *) ¤t_section->use) = (short) width2t; if (*((short *) ¤t_section->use) != width2t) *((short *) ¤t_section->use) = SHRT_MAX; /* Can't happen */ } } if (d->type == END) break; if (d->type == SEC) { current_section = d; width1r = 0; width1t = 0; width2r = 0; width2t = 0; continue; } { /* Width of column 1 (synopsis) */ size_t wr = 1 + strlen (d->com); size_t wt = wr; if (d->use != NULL) { const char *u; wr++; wt++; for (u = d->use; *u != '\0'; u++) { if (*u != '<' && *u != '>') wr++; wt++; } } if (wr > width1r) width1r = wr; if (wt > width1t) width1t = wt; } { /* Width of column 2 (description) */ const char *desc; size_t wr = 0; size_t wt = 0; for (desc = d->help; *desc != '\0'; desc++) { if (*desc < '\1' || *desc > '\3') wr++; if (*desc < '\1' || *desc > '\3') wt++; } if (wr > width2r) width2r = wr; if (wt > width2t) width2t = wt; } } } /* * is_prefix - tell whether a string an initial prefix of another * * Return * 0 if s1 is not a prefix of s2 * 1 if s1 is a prefix of s2 * >1 if s1 is equal to s2 */ static int is_prefix (const char *s1, const char *s2) { for (;; s1++, s2++) { if (*s1 == '\0') return (*s2 == '\0') ? 2 : 1; if (*s2 != *s1) return 0; } } /* * call_opt * Equivalent to having the same option on the command line */ static void call_opt (comfun_t func, ...) { int argc; const char *argv[10]; va_list args; va_start (args, func); for (argc = 0; argc < sizeof argv / sizeof *argv; argc++) { argv[argc] = va_arg (args, const char *); if (argv[argc] == NULL) { argc++; break; } } func (argc, argv); } #endif /*DeuTex and DeuSF*/ deutex-4.4.902/src/endianio.c0000644000324500032450000000773510304422151015315 0ustar aymaym00000000000000/* * endianio.c - file I/O with explicit endianness * * Those functions allow to read little-endian and * big-endian integers from a file regardless of the * endianness of the CPU. * * This code has been tested on 16-bit and 32-bit C * compilers. * * Adapted from Yadex by AYM on 1999-03-06. */ /* This file is Copyright © 1999-2005 André Majorel. This file is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This file 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 Library 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include "endianio.h" /* * fread_i16_be * Read a big-endian 16-bit signed integer from file . * Returns 0 on success, != 0 on failure. */ int fread_i16_be (FILE *fd, int16_t *buf) { *buf = (getc (fd) << 8) | getc (fd); return feof (fd) || ferror (fd); } /* * fread_i16_le * Read a little-endian 16-bit signed integer from file . * Returns 0 on success, != 0 on failure. */ int fread_i16_le (FILE *fd, int16_t *buf) { *buf = getc (fd) | (getc (fd) << 8); return feof (fd) || ferror (fd); } /* * fread_i32_be * Read a big-endian 32-bit signed integer from file . * Returns 0 on success, != 0 on failure. */ int fread_i32_be (FILE *fd, int32_t *buf) { *buf = ((int32_t) getc (fd) << 24) | ((int32_t) getc (fd) << 16) | ((uint16_t) getc (fd) << 8) | getc (fd); return feof (fd) || ferror (fd); } /* * fread_i32_le * Read a little-endian 32-bit signed integer from file . * Returns 0 on success, != 0 on failure. */ int fread_i32_le (FILE *fd, int32_t *buf) { *buf = getc (fd) | ((uint16_t) getc (fd) << 8) | ((int32_t) getc (fd) << 16) | ((int32_t) getc (fd) << 24); return feof (fd) || ferror (fd); } /* * fread_u16_le * Read a little-endian 16-bit unsigned integer from file . * Returns 0 on success, != 0 on failure. */ int fread_u16_le (FILE *fd, uint16_t *buf) { *buf = getc (fd) | (getc (fd) << 8); return feof (fd) || ferror (fd); } /* * fwrite_i16_le * Write a little-endian 16-bit signed integer to file . * Returns 0 on success, != 0 on failure. */ int fwrite_i16_le (FILE *fd, int16_t buf) { putc ( buf & 0xff, fd); putc ((buf >> 8) & 0xff, fd); return feof (fd) || ferror (fd); } /* * fwrite_i16_be * Write a big-endian 16-bit signed integer to file . * Returns 0 on success, != 0 on failure. */ int fwrite_i16_be (FILE *fd, int16_t buf) { putc ((buf >> 8) & 0xff, fd); putc ( buf & 0xff, fd); return feof (fd) || ferror (fd); } /* * fwrite_i32_le * Write a little-endian 32-bit signed integer to file . * Returns 0 on success, != 0 on failure. */ int fwrite_i32_le (FILE *fd, int32_t buf) { putc ( buf & 0xff, fd); putc ((buf >> 8) & 0xff, fd); putc ((buf >> 16) & 0xff, fd); putc ((buf >> 24) & 0xff, fd); return feof (fd) || ferror (fd); } /* * fwrite_i32_be * Write a big-endian 32-bit signed integer to file . * Returns 0 on success, != 0 on failure. */ int fwrite_i32_be (FILE *fd, int32_t buf) { putc ((buf >> 24) & 0xff, fd); putc ((buf >> 16) & 0xff, fd); putc ((buf >> 8) & 0xff, fd); putc ( buf & 0xff, fd); return feof (fd) || ferror (fd); } /* * fwrite_u16_le * Write a little-endian 16-bit unsigned integer to file . * Returns 0 on success, != 0 on failure. */ int fwrite_u16_le (FILE *fd, uint16_t buf) { putc ( buf & 0xff, fd); putc ((buf >> 8) & 0xff, fd); return feof (fd) || ferror (fd); } deutex-4.4.902/src/endianm.c0000644000324500032450000000726010304422221015131 0ustar aymaym00000000000000/* * endianm.c * Endianness-independant memory access. * * Those functions allow to retrieve little-endian and * big-endian integers from a memory area regardless of * the endianness of the CPU. * * This code has been tested on 16-bit and 32-bit C * compilers. * * AYM 1999-07-04 */ /* This file is Copyright © 1999-2005 André Majorel. This file is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This file 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 Library 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include "endianm.h" /* * read_i16_le * Read a little-endian 16-bit signed integer from memory area * pointed to by . */ void read_i16_le (const void *ptr, i16 *buf) { *buf = ((const unsigned char *) ptr)[0] | (((const unsigned char *) ptr)[1] << 8); } /* * read_i32_le * Read a little-endian 32-bit signed integer from memory area * pointed to by . */ void read_i32_le (const void *ptr, i32 *buf) { *buf = ((const unsigned char *) ptr)[0] | ((u16) ((const unsigned char *) ptr)[1] << 8) | ((i32) ((const unsigned char *) ptr)[2] << 16) | ((i32) ((const unsigned char *) ptr)[3] << 24); } /* * peek_i16_le * Read a little-endian 16-bit signed integer from memory area * pointed to by . */ i16 peek_i16_le (const void *ptr) { return ((const unsigned char *) ptr)[0] | (((const unsigned char *) ptr)[1] << 8); } /* * peek_u16_le * Read a little-endian 16-bit unsigned integer from memory area * pointed to by . */ u16 peek_u16_le (const void *ptr) { return ((const unsigned char *) ptr)[0] | (((const unsigned char *) ptr)[1] << 8); } /* * peek_i32_be * Read a big-endian 32-bit signed integer from memory area * pointed to by . */ i32 peek_i32_be (const void *ptr) { return ((i32) (((const unsigned char *) ptr)[0]) << 24) | ((i32) (((const unsigned char *) ptr)[1]) << 16) | ((u16) (((const unsigned char *) ptr)[2]) << 8) | ((const unsigned char *) ptr)[3]; } /* * peek_i32_le * Read a little-endian 32-bit signed integer from memory area * pointed to by . */ i32 peek_i32_le (const void *ptr) { return ((const unsigned char *) ptr)[0] | ((u16) ((const unsigned char *) ptr)[1] << 8) | ((i32) ((const unsigned char *) ptr)[2] << 16) | ((i32) ((const unsigned char *) ptr)[3] << 24); } /* * write_i16_le * Write a little-endian 16-bit signed integer to memory area * pointed to by . */ void write_i16_le (void *ptr, i16 val) { ((unsigned char *) ptr)[0] = val; ((unsigned char *) ptr)[1] = val >> 8; } /* * write_i32_be * Write a big-endian 32-bit signed integer to memory area * pointed to by . */ void write_i32_be (void *ptr, i32 val) { ((unsigned char *) ptr)[0] = val >> 24; ((unsigned char *) ptr)[1] = val >> 16; ((unsigned char *) ptr)[2] = val >> 8; ((unsigned char *) ptr)[3] = val; } /* * write_i32_le * Write a little-endian 32-bit signed integer to memory area * pointed to by . */ void write_i32_le (void *ptr, i32 val) { ((unsigned char *) ptr)[0] = val; ((unsigned char *) ptr)[1] = val >> 8; ((unsigned char *) ptr)[2] = val >> 16; ((unsigned char *) ptr)[3] = val >> 24; } deutex-4.4.902/src/extract.c0000644000324500032450000006643010305321164015201 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include "tools.h" #include "endianm.h" #include "text.h" #include "mkwad.h" #include "texture.h" #include "ident.h" #include "color.h" #include "picture.h" #include "sound.h" #include "sscript.h" #include "usedidx.h" /*compile only for DeuTex*/ #if defined DeuTex /************** Begin XTRACT WAD module **************/ /* ** here we go for some real indecent programming. sorry */ extern char file[128]; /* DEBUG */ #if 0 static void stop (void) { ; } #endif /* ** try to save entry as BitMap .BMP */ static Bool XTRbmpSave(Int16 *pinsrX,Int16 *pinsrY,struct WADDIR *entry, PICTYPE type,const char *DataDir,const char *dir,struct WADINFO *info,IMGTYPE Picture,Bool WSafe, cusage_t *cusage) { Bool res; Int32 start=entry->start; Int32 size =entry->size; char *name=entry->name; char *buffer; char *extens=NULL; if(size<8L) return FALSE; switch(Picture) { case PICGIF: extens="GIF";break; case PICBMP: extens="BMP";break; case PICPPM: extens="PPM";break; case PICTGA: extens="TGA";break; default: Bug("EX47", "Invalid img type %d", (int) Picture); } res = MakeFileName(file,DataDir,dir,"",name,extens); if((WSafe==TRUE)&&(res==TRUE)) { Warning("EX48", "Will not overwrite file %s",file); return TRUE; } buffer=(char *)Malloc(size); WADRseek(info,start); WADRreadBytes(info,buffer,size); res = PICsaveInFile(file,type,buffer,size,pinsrX,pinsrY,Picture, name, cusage); if(res==TRUE)Detail("EX49", "Saved picture as %s", fname (file)); Free(buffer); return res; } /* ** extract entries from a WAD ** ** Called with cusage == NULL, (-xtract) this function extracts ** everything in the wad to separate files. ** ** Called with cusage != NULL, (-usedidx) this function creates ** no files but print statistics about which colours are used ** in the wad. */ void XTRextractWAD(const char *doomwad, const char *DataDir, const char *wadin, const char *wadinfo, IMGTYPE Picture,SNDTYPE Sound,Bool fullSND,NTRYB select, char trnR, char trnG, char trnB,Bool WSafe, cusage_t *cusage) { static struct WADINFO pwad; static struct WADINFO iwad; static struct WADINFO lwad; struct WADDIR *pdir; Int16 pnb; ENTRY *piden; Int16 p; Int32 ostart,osize; char *buffer; Bool res; Int16 insrX=0,insrY=0; Bool EntryFound; char *extens=NULL; /*text file to write*/ static struct TXTFILE *TXT = NULL; Phase("EX00", "Extracting entries from wad %s", wadin); /*open iwad,get iwad directory*/ iwad.ok=0; WADRopenR(&iwad,doomwad); /* If -usedidx, we're only interested in graphics. */ if (cusage != NULL) select &= (BGRAPHIC | BSPRITE | BPATCH | BFLAT | BSNEAP | BSNEAT | BWALL); /*read WAD*/ pwad.ok=0; WADRopenR(&pwad,wadin); pdir=pwad.dir; pnb=(Int16)pwad.ntry; /*find PNAMES*/ { Int16 pnm=WADRfindEntry(&iwad,"PNAMES"); char *Pnam=NULL; Int32 Pnamsz=0; if(pnm<0) Warning("EX01", "Iwad: no PNAMES lump"); else Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz); piden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz); if(Pnam!=NULL) Free(Pnam); } /* ** prepare for graphics */ /* Read PLAYPAL */ { const char *lumpname = palette_lump; struct WADINFO *wad; Int16 lumpnum; char *lumpdata = NULL; Int32 lumpsz; wad = &pwad; lumpnum = WADRfindEntry (wad, lumpname); if (lumpnum >= 0) lumpdata = WADRreadEntry (wad, lumpnum, &lumpsz); else { wad = &iwad; lumpnum = WADRfindEntry (wad, lumpname); if (lumpnum >= 0) lumpdata = WADRreadEntry (wad, lumpnum, &lumpsz); else { long n; wad = NULL; lumpdata = Malloc (768); Warning ("EX02", "No %s lump found, making up a palette", lumpname); for (n = 0; n < 256; n++) { lumpdata[3*n] = n; lumpdata[3*n+1] = (n & 0x7f) << 1; lumpdata[3*n+2] = (n & 0x3f) << 2; } } } COLinit (trnR, trnG, trnB, lumpdata, (Int16) lumpsz, (wad == NULL) ? "(nofile)" : wad->filename, lumpname); Free (lumpdata); } /* If TITLEPAL exists, read the first 768 bytes of it. But don't prepare COLpal2 because we don't know yet whether we need it. Indeed, if there are no sneats to extract, we're not interested in seeing any TITLEPAL-related warnings. */ { int n; char *titlepal_data = NULL; Int32 titlepal_size = 3 * NCOLOURS; n = WADRfindEntry (&pwad, "TITLEPAL"); if (n >= 0) titlepal_data = WADRreadEntry2 (&pwad, n, &titlepal_size); else { n = WADRfindEntry (&iwad, "TITLEPAL"); if (n >= 0) titlepal_data = WADRreadEntry2 (&iwad, n, &titlepal_size); else { titlepal_data = NULL; titlepal_size = 0; } } COLinitAlt (titlepal_data, titlepal_size); } /* ** read the PNAMES entry in PWAD ** or in DOOM.WAD if it does not exist elsewhere */ do { Int16 pnm=WADRfindEntry(&pwad,"PNAMES"); char *Pnam; Int32 lumpsz; if(pnm>=0) Pnam=WADRreadEntry(&pwad,pnm,&lumpsz); else { pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) { Warning("EX03", "Iwad: no PNAMES lump (2)"); break; } Pnam=WADRreadEntry(&iwad,pnm,&lumpsz); } PNMinit(Pnam,lumpsz); Free(Pnam); } while (0); /* ** iwad not needed anymore */ WADRclose(&iwad); /* ** output WAD creation directives ** and save entries depending on their type. ** If -usedidx, do _not_ create a directives file. */ if (cusage != NULL) TXT = &TXTdummy; /* Notional >/dev/null */ else { /*check if file exists*/ TXT=TXTopenW(wadinfo); { char comment[81]; sprintf (comment, "DeuTex %.32s by Olivier Montanuy", deutex_version); TXTaddComment (TXT, comment); } TXTaddComment(TXT,"PWAD creation directives"); } /* ** LEVELS */ if(select&BLEVEL) { Phase("EX10", "Extracting levels..."); for(EntryFound=FALSE,p=0;puses[n], n, cusage->nlumps[n], (cusage->uses[n] == 0) ? "" : lump_name (cusage->where_first[n])); putchar ('\n'); } /* ** exit graphics and end */ COLfree(); Free(piden); WADRclose(&pwad); TXTaddEmptyLine (TXT); TXTaddComment(TXT,"End of extraction"); TXTcloseW(TXT); Phase("EX99", "End of extraction"); } /*********** End Xtract Module ***************/ void XTRgetEntry(const char *doomwad, const char *DataDir, const char *wadin, const char *entry, IMGTYPE Picture,SNDTYPE Sound,Bool fullSND, char trnR, char trnG, char trnB) { static struct WADINFO pwad; static struct WADINFO iwad; static char Name[8]; Int16 e; char *Entry; Int32 Entrysz; char *Colors=NULL; Int16 insrX,insrY; char *extens=NULL; Bool Found=FALSE; Normalise(Name,entry); iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PLAYPAL*/ e=WADRfindEntry(&iwad,palette_lump); if(e>=0) Colors=WADRreadEntry(&iwad,e,&Entrysz); else ProgError("GE00", "%s: no %s lump in the iwad", fname (iwad.filename), lump_name (palette_lump)); WADRclose(&iwad); pwad.ok=0; WADRopenR(&pwad,wadin); e=WADRfindEntry(&pwad,palette_lump); if(e>=0) { Free(Colors); Colors=WADRreadEntry(&pwad,e,&Entrysz); } COLinit(trnR,trnG,trnB,Colors,(Int16)Entrysz, pwad.filename, palette_lump); Free(Colors); e=WADRfindEntry(&pwad,Name); if(e<0) ProgError("GE01", "%s: %s: lump not found", fname (pwad.filename), lump_name (entry)); Phase("GE02", "%s: %s: extracting", fname (wadin), lump_name (entry)); Entry=WADRreadEntry(&pwad,e,&Entrysz); /*try graphic*/ if(Found!=TRUE) if(Entrysz>8) { switch(Picture) { case PICGIF: extens="GIF";break; case PICBMP: extens="BMP";break; case PICPPM: extens="PPM";break; case PICTGA: extens="TGA";break; default: Bug("GE03", "Invalid img type %d", (int) Picture); } MakeFileName(file,DataDir,"","",Name,extens); if(PICsaveInFile(file,PGRAPH,Entry,Entrysz,&insrX,&insrY,Picture, Name, NULL) ==TRUE) { Info("GE04", "Picture insertion point is (%d,%d)",insrX,insrY); Found=TRUE; } /* FIXME try wall as well ? */ else if((Entrysz==0x1000)||(Entrysz==0x1040)) { if(PICsaveInFile(file,PFLAT,Entry,Entrysz,&insrX,&insrY,Picture, Name, NULL) ==TRUE) { Found=TRUE; } } else if(Entrysz==64000L) { if(PICsaveInFile(file,PLUMP,Entry,Entrysz,&insrX,&insrY,Picture, Name, NULL) ==TRUE) { Found=TRUE; } } } if (Found!=TRUE) if (peek_i16_le (Entry) == 3) if (Entrysz >= 8 + peek_i32_le (Entry + 4)) { /*save as sound*/ switch(Sound) { case SNDAU: extens="AU";break; case SNDWAV: extens="WAV";break; case SNDVOC: extens="VOC";break; default: Bug("GE05", "Invalid snd type %d", (int) Sound); } MakeFileName(file,DataDir,"","",Name,extens); SNDsaveSound(file,Entry,Entrysz,Sound,fullSND, Name); Found=TRUE; } if(Found!=TRUE) { /*save as lump*/ MakeFileName(file,DataDir,"","",Name,"LMP"); WADRsaveEntry(&pwad,e,file); } Free(Entry); WADRclose(&pwad); } #endif /*DeuTex*/ deutex-4.4.902/src/gifcodec.c0000644000324500032450000003025207307443545015303 0ustar aymaym00000000000000/* The LZW CODEC for GIF is Copyright (c) 1995 David Kaplan Alas, This LZW DECODER doesn't work yet. In fact this file is not used at all. All the GIF stuff is really in lzw.c. -- AYM 1999-09-07 */ #include "deutex.h" /*for types. equivalent of deu.h*/ #if defined DeuTex /*deutex shit*/ #if NEWGIFE || NEWGIFD #include #include #include #include "gifcodec.h" /* local defines */ #define HASHSIZE 5101 #define TABLESIZE 4096 #define HASHBITS 4 #define OK 0 #define EMPTY -1 #define BAD_ALLOC -2 #define OVERFLOW -3 #define OUTOFSYNC -4 static void Enc_clear(void); static void putCode(Int16 code); static Int16 flush(void); static Int16 findStr(Int16 pfx, Int16 sfx); static void putCode(Int16 code); static Int16 putbyte(Int16 byt); static UInt8 buffer[255]; /* the write buffer */ /* tables */ static Int16 *codes; /* the code entry column of the table */ static Int16 *prefix; /* the prefix entry column of the table */ static Int16 *suffix; /* the suffix entry column of the table */ /* codes */ static Int16 clrc; /* the value of the clearcode (the minsize + 1) */ static Int16 endc; /* the value of the endcode (the minsize + 2) */ /* control */ static Int16 nroots; /* how many codes are already in use = bitlength of the pixels*/ /* 1 << pixelsize */ static Int16 minsize; /* the minimum size for the first code (the highest value for the bitlength of the pixels*/ static Int16 cursize; /* the current bitlength being used in the codes */ static Int16 maxsize; /* the maximum bitlength that can be used (8) */ static Int16 curcode; /* the next entry value that is available */ static Int16 maxcode; /* the maximum entry value of the table */ static Int16 bytecode; /* last code read or written */ static Int16 bytemask; /* mask for bytecode */ static Int16 nbytes; /* COD the number of bytes that have been written */ /* DEC bytes in buffer */ static Int16 nbits; /* COD the number of bits being used in the highest empty slot */ /* DEC current element width */ #endif /*NEWGIFE NEWGIFD*/ /* ENCODER */ #if NEWGIFE FILE* outfile; /* the file to be written to */ static Int16 chrc; /* COD the current byte being read */ static Int16 strc; /* COD the number of the last entry to have a match */ static Int16 started; /* a boolean variable used to see if this is the first string */ /* Initializes all the variables (yup, all them up there!) */ Int16 InitEncoder(FILE* out, Int16 bpp) { codes = (Int16 *) malloc(sizeof(Int16)*HASHSIZE); prefix = (Int16 *) malloc(sizeof(Int16)*HASHSIZE); suffix = (Int16 *) malloc(sizeof(Int16)*HASHSIZE); if((codes == NULL) || (prefix == NULL) || (suffix == NULL)) return BAD_ALLOC; outfile = out; chrc = strc = started = 0; minsize = bpp + 1; maxsize = 12; nroots = 1 << bpp; clrc = nroots; endc = clrc + 1; bytecode = 0; bytemask = 1; nbytes = 0; started = 0; Enc_clear(); putCode(clrc); return OK; } Int16 ExitEncoder(void) { flush(); free(codes); free(prefix); free(suffix); return 0; } /* Encodes one string of bytes and writes to the current file pointer */ /* I will comment this part heavily to illustrate the process... */ Int16 Encode(UInt8 *buf, Int32 size) { Int16 pos = 0, index; /* if this is the first table to be used, setup some variables we need such as the table's first entry: the first byte in the array */ if(!started) { strc = buf[pos++]; /* changed pos+1 to pos++ */ started = 1; } /* go through the array of bytes */ while(pos <= size) { chrc = buf[pos++]; /* get the next (or first) character */ /* see if the current string (be it one character or more) is in the table and return the corresponding entry number. If not, return the number of the next available entry */ index = findStr(strc, chrc); /* if the string IS in the index, we will get a number that corresponds to a string in the table: it wont be empty */ if(codes[index] != EMPTY) /* string found! */ { /* set the current string to the one-byte code for the string that was found */ strc = codes[index]; } else /* not found! */ { /* set the next entry in the table to the next available entry number */ codes[index] = curcode; prefix[index] = strc; /* set the prefix entry to the strc */ suffix[index] = chrc; /* set the suffix entry to the chrc */ putCode(strc); /* put the code into the out file (compression!) */ strc = chrc; /* set the prefix to the current char */ curcode++; /* remember that the current entry is now filled */ /* if the number of bytes in the current code is as big as possible, we must reset the table! */ if(curcode > maxcode) { cursize++; /* set the currentsize of the code to the next number */ /* if the current # of bytes being used exceeds the max */ if(cursize > maxsize) { putCode(clrc); /* put a clearcode into the file to tell the decoder */ Enc_clear(); /* reset the table and start over */ } else /* if not */ { nbits = cursize; /* set the number of bits to the current size */ maxcode <<= 1; /* set maxcode to the current char bitshifted once */ if(cursize == maxsize) /* if we are at the last bit-increase */ maxcode--; /* make maxcode one less so curcode can be larger than it */ } } } } return OK; } /* close the table: */ Int16 flush(void) { putCode(endc); /* put an endcode in the file */ if(bytemask != 1) /* if the last string was less than 256 bytes */ { putbyte(bytecode); /* put the last byte into the file */ bytecode = 0; /* and reset the variables*/ bytemask = 1; } if(nbytes > 0) /* if the last string has anything in it */ { fputc(nbytes, outfile); /* write the block out */ fwrite(buffer, nbytes, 1, outfile); nbytes = 0; } return ferror(outfile) ? BAD_ALLOC : OK; } /* put the code in. This is tricky because we use an int and we might have a code that is only using 7 or less bits, we must compensate */ void putCode(Int16 code) { Int16 mask = 1; Int16 n = nbits; while(n-- >0) { if(code & mask) bytecode |= bytemask; if((bytemask <<=1) > 0x80) { putbyte(bytecode); bytecode = 0; bytemask = 1; } mask <<= 1; } } /* clear the table for a new one to be built */ void Enc_clear(void) { Int16 i; cursize = minsize; nbits = cursize; curcode = endc + 1; maxcode = 1 << cursize; for(i=0;i 0) && (nb < rwbytes) ) bytes[nb++] = stack[--stkp]; /* loop until a row has been decoded */ while( nb < rwbytes ) { /*....... get next code */ if( (code=getcode()) < 0 ) break; /*....... check for a clear code*/ if( code == clrc ) { reset_decoder(); if( oldc == endc ) break; bytes[nb++] = oldc; if( nb == rwbytes ) break; } /*....... check for an end code*/ else if( code == endc ) { break; } /*....... code is a data code*/ else { if( code == curcode ) { code = oldc; cond = push( newc ); } else if( code > curcode ) { cond = OUTOFSYNC; break; } while( code > endc ) { cond = push( (suffix[code]&0xFF) ); code = prefix[code]; } cond = push( code ); /* add code to table */ if( curcode < maxcode ) { newc = code; suffix[curcode] = newc; prefix[curcode] = oldc; oldc = bitcode; curcode++; } /* current width exhausted? */ if( curcode >= maxcode ) { if( cursize < maxsize ) { cursize++; nbits = cursize; maxcode <<= 1; } else if( (code=getcode()) == clrc ) { reset_decoder(); if( oldc == endc ) break; bytes[nb++] = oldc; if( nb == rwbytes ) break; } else { cond = OVERFLOW; break; } } /* transfer string from stack to buffer*/ while( (stkp > 0) && (nb < rwbytes) ) bytes[nb++] = stack[--stkp]; } } /*! David I use fmemcpy not memcpy, because data is FAR (char *) */ _fmemcpy( buf, bytes, npxls ); return cond; } void Dec_clear(void) { Int16 i; cursize = minsize; nbits = cursize; clrc = nroots; endc = clrc + 1; curcode = endc + 1; maxcode = 1 << cursize; for(i=0; i 0 ) */ for(n=0; n 0x80 ) { bytemask = 1; if( (bytecode = getbyte()) < 0 ) return -1; } if( bytecode & bytemask ) bitcode |= bitmask; bitmask <<= 1; } return bitcode; } /* get a byte block */ Int16 getbyte( void ) { if( curbyte >= nbytes ) /*need a new block*/ { /*! David the block size is an unsigned char MODIFIED if( (nbytes = fgetc( ifile )&) < 1 ) return -1; */ for(nbytes=0;nbytes==0;) /*get a non zero block*/ { if( (nbytes = fgetc( ifile )) == EOF ) return -1; nbytes &= 0xFF; } if(fread( buffer, nbytes, 1, ifile ) != 1 ) return -1; curbyte = 0; } return buffer[curbyte++]; } void reset_decoder(void) { stkp = 0; Dec_clear(); while( (oldc=getcode()) == clrc ); newc = oldc; } #endif /*NEWGIFD*/ #endif /*DeuTex*/ deutex-4.4.902/src/ident.c0000644000324500032450000007543110304422320014626 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include "tools.h" #include "endianm.h" #include "mkwad.h" #include "picture.h" #include "texture.h" #include "ident.h" /* ** This file contains all the routines to identify DOOM specific ** entries and structures. Fear the bugs! */ /* Functions that are going to call IDENTsetType() or IDENTdirSet() put their name here before. Thus, with -di, IDENTsetType() and IDENTdirSet() can print the name of the function that actually did the identification--their caller. */ static const char *ident_func = NULL; /****************IDENT module ***********************/ /* identify ExMx or MAPxx entries ** which begin a DOOM level. ** returns -1 if not correct */ /* Doom, Doom II, Heretic, Hexen and Strife */ static const struct { const char *name; char mandatory; /* If non-zero, warn if lump is missing */ char level_format; /* 'n' : denotes Doom/Heretic/Hexen/Strife 'a' : denotes Doom alpha '?' : can belong to either */ const char *flags; } Part[] = { { "name", 1, '?', NULL }, { "BEHAVIOR", 0, 'n', "n11" }, /* Hexen only */ { "BLOCKMAP", 1, 'n', "n10" }, { "FLATNAME", 1, 'a', "a1" }, /* Doom alpha 0.4 and 0.5 only */ { "LINEDEFS", 1, 'n', "n2" }, { "LINES", 1, 'a', "a3" }, /* Doom alpha 0.4 and 0.5 only */ { "NODES", 1, 'n', "n7" }, { "POINTS", 1, 'a', "a2" }, /* Doom alpha 0.4 and 0.5 only */ { "REJECT", 1, 'n', "n9" }, /* Not in Doom PR */ { "SECTORS", 1, '?', "a4n8" }, { "SEGS", 1, 'n', "n5" }, { "SIDEDEFS", 1, 'n', "n3" }, { "SSECTORS", 1, 'n', "n6" }, { "THINGS", 1, '?', "a5n1" }, { "VERTEXES", 1, 'n', "n4" }, }; static int IDENTlevelPartMax (void) { return sizeof Part / sizeof *Part - 1; } int IDENTlevelPart (const char *name) { int n; for (n = 1; n < sizeof Part / sizeof *Part; n++) { if (strncmp (Part[n].name, name, 8) == 0) return n; } return -1; } Int16 IDENTlevel(const char *buffer) { if (buffer[0] == 'E' && buffer[1] >= '1' && buffer[1] <= '9' && buffer[2] == 'M' && buffer[3] >= '1' && buffer[3] <= '9') { /* ExMy */ if (buffer[4] == '\0') return ((buffer[1] & 0x0f) << 4) + (buffer[3] & 0x0f); /* ExMyz -- Doom alpha */ if (buffer[4] >= '0' && buffer[4] <= '9' && buffer[5] == '\0') { int r = 100 * (buffer[1] - '0') + 10 * (buffer[3] - '0') + buffer[4]-'0'; if (r & EMASK) return -1; /* Overflow. E2M55 is the limit. */ return r; } } /* MAPxy */ if (buffer[0] == 'M' && buffer[1]=='A' && buffer[2]=='P' && buffer[3]>='0' && buffer[3]<='9' && buffer[4]>='0' && buffer[4]<='9') return (Int16)((buffer[3]&0xF)*10)+(buffer[4]&0xF); return -1; } /* ** calculate default insertion point */ Int16 IDENTinsrX(PICTYPE type,Int16 insrX,Int16 szx) { if(insrX!=INVALIDINT) if(insrX > -4096) if(insrX < 4096) return insrX; /* default insertion point */ switch(type) { case PPATCH: /*mid, lower-5 ????*/ return (Int16)(szx/2); case PSPRIT: /*mid, lower-5*/ return (Int16)(szx/2); case PWEAPN: /*absolute, in 320*200*/ return (Int16)(-(320-szx)/2); /* -160+X??*/ case PFLAT: /*no insertion point*/ case PLUMP: /*no insertion point*/ case PWALL: /*no insertion point*/ return (Int16)0; case PGRAPH: /*0,0 by default*/ return (Int16)0; default: Bug("FB25", "Idinx (%d)", (int) type); } return (Int16)0; } Int16 IDENTinsrY(PICTYPE type,Int16 insrY,Int16 szy) { if(insrY!=INVALIDINT) if(insrY > -4096) if(insrY < 4096) return insrY; /* default insertion point */ switch(type) { case PPATCH: /*mid, lower-5 ????*/ return (Int16)(szy-5); case PSPRIT: /*mid, lower-5*/ return (Int16)(szy-5); case PWEAPN: /*absolute, in 320*200*/ return (Int16)(-(200-szy)); case PFLAT: /*no insertion point*/ case PLUMP: /*no insertion point*/ case PWALL: /*no insertion point*/ return (Int16)0; case PGRAPH: /*0,0 by default*/ return (Int16)0; default: Bug("FB35", "Idiny (%d)", (int) type); } return 0; } /* * IDENTgraphic * Look at the contents of lump number from wad * and return the probability that it contained a picture, * from 0 to 100. */ int IDENTgraphic(struct WADINFO *info,Int16 n) { Int32 start=info->dir[n].start; Int32 size=info->dir[n].size; unsigned char *buf; pic_head_t h; int x; int bad_order = 0; Int32 ofs_prev = 0xdeadbeef; /* Slurp the whole lump. */ buf = Malloc (size); WADRseek(info,start); WADRreadBytes (info, buf, size); /* If parse_pic_header() chokes, it must not be a valid picture */ if (parse_pic_header (buf, size, &h, NULL)) { Free (buf); return 0; } /* Be even more paranoid than parse_pic_header(): check column offsets */ bad_order = 0; for (x = 0; x < h.width; x++) { Int32 ofs = 0xdeadbeef; /* Cut and pasted from picture.c. Bleagh. */ if (h.colofs_size == 4) { Int32 o; read_i32_le (((const Int32 *) h.colofs) + x, &o); ofs = o; } else if (h.colofs_size == 2) { /* In principle, the offset is signed. However, considering it unsigned helps extracting patches larger than 32 kB, like W18_1 (alpha) or SKY* (PR). Interestingly, Doom alpha and Doom PR treat the offset as signed, which is why some textures appear with tutti-frutti on the right. -- AYM 1999-09-18 */ UInt16 o; read_i16_le (((const Int16 *) h.colofs) + x, (Int16 *) &o); ofs = o; } else { /* Can't happen */ Bug ("ID65", "Invalid colofs_size %d", (int) h.colofs_size); } if (buf + ofs < h.data || ofs >= size) { Free (buf); return 0; } /* In a picture lump, columns appear in increasing X order. This is not mandated but, in practice, I think it's always true. If they're not, the lump is somewhat suspicious and therefore, this function returns only 50. This additional checking allows us not to mistake Doom alpha 0.4 WORLD1 for a picture. It's really a snea but it passes all the other tests of picturehood. */ if (x > 0) { Int32 delta_ofs = ofs - ofs_prev; if (delta_ofs < 1) bad_order++; } ofs_prev = ofs; } /*valid...graphic...maybe...*/ Free (buf); if (bad_order) return 50; else return 100; } /* * IDENTsnea * Look at the contents of lump number from wad * and return the probability that it contained a snea, * from 0 to 100. * * The snea format was used for certain graphics in Doom * alpha 0.4 and 0.5. It consists in a 2-byte header * followed by an interleaved bitmap. The first byte, W, is * the quarter of the width. The second byte, H is the * height. The bitmap is made of 4xWxH bytes. The first WxH * bytes contain the bitmap for columns 0, 4, 8, etc. The * next WxH bytes contain the bitmap for columns 1, 5, 9, * etc., and so on. No transparency. */ int IDENTsnea (struct WADINFO *info, Int16 n) { unsigned char width; unsigned char height; if (info->dir[n].size < 2) return 0; WADRseek (info, info->dir[n].start); WADRreadBytes (info, &width, 1); WADRreadBytes (info, &height, 1); if (info->dir[n].size - 2 != 4l * width * height) return 0; return 100; } /* ** set identity of an entry with known name ** set only the first entry that match this name */ static void IDENTdirSet (ENTRY *ids, struct WADINFO *info, const char *name, ENTRY ident) { Int16 n; n=WADRfindEntry(info,name); if(n>=0) /*found it?*/ if(n<(info->ntry)) if(ids[n]==EZZZZ) { if (debug_ident != NULL && ((debug_ident[0] == '*' && debug_ident[1] == '\0') || ! strncmp (debug_ident, name, 8))) Info ("ID90", "Ident: %-8s as %-8.32s by %.32s", lump_name (name), entry_type_name (ident), ident_func); ids[n]=ident; } } /* * IDENTsetType * Set the type of an entry */ static void IDENTsetType (ENTRY *ids, struct WADINFO *info, int n, ENTRY type) { if (debug_ident != NULL && ((debug_ident[0] == '*' && debug_ident[1] == '\0') || ! strncmp (debug_ident, info->dir[n].name, 8))) Info ("ID91", "Ident: %-8s as %-8.32s by %.32s", lump_name (info->dir[n].name), entry_type_name (type), ident_func); ids[n] = type; } /* ** identifies sprites from: ** S_START SS_START S_END SS_END delimiters if exist ** S_END SS_END delimiter and crawl back ** ** Precond: ids contains EZZZZ for unidentified entries */ static void IDENTdirSprites(ENTRY *ids,struct WADINFO *info,Bool Check) { Int16 s_end,s_start; Int16 n; ident_func = "IDENTdirSprites"; /* ** check if there are sprites */ s_end=WADRfindEntry(info,"S_END"); if(s_end<0) s_end=WADRfindEntry(info,"SS_END"); if(s_end<0) return; IDENTsetType (ids, info, s_end, EVOID); /* ** check if there is a sprites begining */ s_start=WADRfindEntry(info,"S_START"); if(s_start<0) s_start=WADRfindEntry(info,"SS_START"); /* ** guess sprite location */ if(s_start<0) { for(n=s_end-1;n>=0;n--) { if(ids[n]!=EZZZZ) break; /*last sprite*/ if(info->dir[n].size<8) break; /*last sprite*/ if(Check==TRUE) { if (IDENTgraphic(info,n) == 0) break; } IDENTsetType (ids, info, n, ESPRITE); } } /* ** declare sprites */ else { IDENTsetType (ids, info, s_start, EVOID); for(n=s_end-1;n>s_start;n--) { if(info->dir[n].size>8) { IDENTsetType (ids, info, n, ESPRITE); } } } } /* ** identifies flats from: ** F_START FF_START F_END FF_END delimiters if exist ** F_END FF_END delimiter and crawl back ** ** Precond: ids contains EZZZZ for unidentified entries */ static void IDENTdirFlats(ENTRY *ids,struct WADINFO *info) { Int16 f_end,f_start; Int16 n; ident_func = "IDENTdirFlats"; /* ** check if there are flats */ f_end=WADRfindEntry(info,"F_END"); if(f_end<0) f_end=WADRfindEntry(info,"FF_END"); if(f_end<0) return; IDENTsetType (ids, info,f_end, EVOID); IDENTdirSet(ids,info,"F1_START",EVOID); IDENTdirSet(ids,info,"F1_END",EVOID); IDENTdirSet(ids,info,"F2_START",EVOID); IDENTdirSet(ids,info,"F2_END",EVOID); IDENTdirSet(ids,info,"F3_START",EVOID); IDENTdirSet(ids,info,"F3_END",EVOID); /*F_SKY1 is not a real flat, but it must be among them*/ IDENTdirSet(ids,info,"F_SKY1",EFLAT); /* ** check if there is a flats begining */ f_start=WADRfindEntry(info,"F_START"); if(f_start<0) f_start=WADRfindEntry(info,"FF_START"); /* ** guess flat location */ if(f_start<0) { for(n=f_end-1;n>0;n--) { if(ids[n]!=EZZZZ) if(ids[n]!=EVOID) if(ids[n]!=EFLAT) break; /*last flat*/ if((info->dir[n].size==0x1000)||(info->dir[n].size==0x2000) ||(info->dir[n].size==0x1040)) { IDENTsetType (ids, info, n, EFLAT); } } } /* ** declare flats */ else { IDENTsetType (ids, info, f_start, EVOID); for(n=f_end-1;n>f_start;n--) { if((info->dir[n].size==0x1000)||(info->dir[n].size==0x2000) ||(info->dir[n].size==0x1040)) { IDENTsetType (ids, info, n, EFLAT); } } } } /* * IDENTdirWalls - identify ROTT walls (WALLSTRT/WALLSTOP) * * Precond: ids contains EZZZZ for unidentified entries */ static void IDENTdirWalls(ENTRY *ids, struct WADINFO *info) { Int16 w_start, w_end; Int16 n; const Int32 WALL_SIZE = 4096; ident_func = "IDENTdirWalls"; w_start = WADRfindEntry (info, "WALLSTRT"); w_end = WADRfindEntry (info, "WALLSTOP"); if (w_start < 0) Warning ("IW05", "No WALLSTRT"); if (w_start < 0) return; if (w_start >= 0 && w_end < 0) Warning ("IW06", "WALLSTRT but no WALLSTOP. Guessing where walls stop."); IDENTdirSet (ids, info, "WALLSTRT", EVOID); IDENTdirSet (ids, info, "WALLSTOP", EVOID); for (n = w_start + 1; n > 0; n++) { if (n >= info->ntry) break; if (w_end >= 0 && n >= w_end) break; if (w_end < 0 && info->dir[n].size != WALL_SIZE) break; if (info->dir[n].size == 0) /* The iwad has empty walls. Ignore them. */ { IDENTsetType (ids, info, n, EVOID); continue; } if (info->dir[n].size != WALL_SIZE) Warning ("IW10", "Wall with size != %ld", (long) WALL_SIZE); if (ids[n] != EZZZZ) Warning ("IW11", "Wall already identified as %d", (int) ids[n]); IDENTsetType (ids, info, n, EWALL); } } /* Is it a good idea to decide a lump is a lump without even looking at it ? Has a potential for breaking when used with different iwads. -- AYM 1999-10-18 */ static void IDENTdirLumps(ENTRY *ids,struct WADINFO *info) { ident_func = "IDENTdirLumps"; IDENTdirSet(ids,info,palette_lump,ELUMP); IDENTdirSet(ids,info,"COLORMAP",ELUMP); IDENTdirSet(ids,info,"ENDOOM",ELUMP); IDENTdirSet(ids,info,"ENDTEXT",ELUMP); IDENTdirSet(ids,info,"DEMO1",ELUMP); IDENTdirSet(ids,info,"DEMO2",ELUMP); IDENTdirSet(ids,info,"DEMO3",ELUMP); IDENTdirSet(ids,info,"LOADING",ELUMP); /*loading screen*/ IDENTdirSet(ids,info,"DMXGUS",ELUMP); IDENTdirSet(ids,info,"GENMIDI",ELUMP); IDENTdirSet(ids,info,"TINTTAB",ELUMP); } static void IDENTdirPatches(ENTRY *ids,struct WADINFO *info, char *Pnam, Int32 Pnamsz,Bool Check) { Int16 p_end,p_start; Int16 n,p; char *Pnames; ident_func = "IDENTdirPatches"; /* ** find texture and pname entries */ if (texture_lump == TL_NORMAL) { IDENTdirSet(ids,info,"TEXTURE1",ETEXTUR+1); IDENTdirSet(ids,info,"TEXTURE2",ETEXTUR+2); } else if (texture_lump == TL_TEXTURES) { IDENTdirSet(ids,info,"TEXTURES",ETEXTUR+1); } else if (texture_lump == TL_NONE) { ; /* No texture lump. Do nothing */ } else { Bug ("IP10", "Invalid tl %d", (int) texture_lump); } IDENTdirSet(ids,info,"PNAMES",EPNAME); /* ** check if there are flats */ p_end=WADRfindEntry(info,"P_END"); if(p_end<0) p_end=WADRfindEntry(info,"PP_END"); if(p_end>=0) { IDENTsetType (ids, info, p_end, EVOID); /* ** check if there is a patch begining */ IDENTdirSet(ids,info,"P1_START",EVOID); IDENTdirSet(ids,info,"P2_START",EVOID); IDENTdirSet(ids,info,"P3_START",EVOID); IDENTdirSet(ids,info,"P1_END",EVOID); IDENTdirSet(ids,info,"P2_END",EVOID); IDENTdirSet(ids,info,"P3_END",EVOID); p_start=WADRfindEntry(info,"P_START"); if(p_start<0) p_start=WADRfindEntry(info,"PP_START"); /* ** declare patches */ if(p_start>=0) { IDENTsetType (ids, info, p_start, EVOID); for(n=p_end-1;n>p_start;n--) { if(info->dir[n].size>8) IDENTsetType (ids, info, n, EPATCH); } } } /* ** check for lost patches ** */ if(Check==TRUE) { /*checkif PNAMES is redefined*/ n=WADRfindEntry(info,"PNAMES"); if(n>=0) { Pnames=(char *)Malloc(info->dir[n].size); WADRseek(info,info->dir[n].start); WADRreadBytes(info,Pnames,info->dir[n].size); PNMinit(Pnames,info->dir[n].size); Free(Pnames); } else /*init with default DOOM Pnames*/ { if(Pnam!=NULL&&Pnamsz!=0) PNMinit(Pnam,Pnamsz); } /*check for lost patches*/ for(n=0;nntry;n++) { if(ids[n]==EZZZZ) if(info->dir[n].size>8) { p=PNMindexOfPatch(info->dir[n].name); /*Gcc*/ if(p>=0) { if (IDENTgraphic(info,n) != 0) IDENTsetType (ids, info, n, EPATCH); } } } PNMfree(); } } /* ** Ident unreferenced graphics */ static void IDENTdirGraphics(ENTRY *ids,struct WADINFO *info) { Int16 n; ident_func = "IDENTdirGraphics"; #if 0 /* Not true for Doom alpha */ IDENTdirSet(ids,info,"TITLEPIC",EGRAPHIC); /* not true for heretic*/ IDENTdirSet(ids,info,"HELP1",EGRAPHIC); IDENTdirSet(ids,info,"HELP2",EGRAPHIC); IDENTdirSet(ids,info,"HELP",EGRAPHIC); IDENTdirSet(ids,info,"CREDIT",EGRAPHIC); IDENTdirSet(ids,info,"TITLE",EGRAPHIC); #endif /*heretic fonts*/ IDENTdirSet(ids,info,"FONTA_S",ELUMP); IDENTdirSet(ids,info,"FONTA_E",ELUMP); IDENTdirSet(ids,info,"FONTB_S",ELUMP); IDENTdirSet(ids,info,"FONTB_E",ELUMP); for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { if(info->dir[n].size>8) { if(strncmp(info->dir[n].name,"FONT",4)==0) { IDENTsetType (ids, info, n, EGRAPHIC); } else if(strncmp(info->dir[n].name,"M_",2)==0) { IDENTsetType (ids, info, n, EGRAPHIC); } } } } } static void IDENTdirGraphics2(ENTRY *ids,struct WADINFO *info,Bool Check) { Int16 n; ident_func = "IDENTdirGraphics2"; for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { if(info->dir[n].size>8) { /* It's not quite clear to me why the following 6 lines are here and not in IDENTdirGraphics(), since these are name-based idents. -- AYM 1999-10-16 */ if(strncmp(info->dir[n].name,"WI",2)==0) { IDENTsetType (ids, info, n, EGRAPHIC); } else if(strncmp(info->dir[n].name,"ST",2)==0) { IDENTsetType (ids, info, n, EGRAPHIC); } else if(Check==TRUE) { int is_picture = IDENTgraphic (info, n); int is_snea = IDENTsnea (info, n); /* Looks more like a picture */ if (is_picture > 0 && is_picture > is_snea) IDENTsetType (ids, info, n, EGRAPHIC); /* Looks more like a snea */ else if (is_snea > 0 && is_snea > is_picture) { if (! strncmp (info->dir[n].name, "TITLEPIC", 8)) IDENTsetType (ids, info, n, ESNEAT); /* Snea, TITLEPAL */ else IDENTsetType (ids, info, n, ESNEAP); /* Snea, PLAYPAL */ } /* Looks like something that the cat brought in :-) */ else { if (is_snea > 0 && is_picture > 0 && is_snea == is_picture) Warning ("IG10", "Ambiguous type for %s (picture or snea ?)", lump_name (info->dir[n].name)); IDENTsetType (ids, info, n, ELUMP); } } else /* Never used. Too dangerous, if you want my opinion. */ { IDENTsetType (ids, info, n, EGRAPHIC); } } } } } /* * IDENTdirSscripts * Identify Strife scripts (SCRIPTnn). This function does * not make sense for other games than Strife. */ static void IDENTdirSscripts(ENTRY *ids,struct WADINFO *info) { Int16 n; ident_func = "IDENTdirSscripts"; for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { if(memcmp(info->dir[n].name,"SCRIPT",6)==0 && isdigit (info->dir[n].name[6]) && isdigit (info->dir[n].name[7])) { IDENTsetType (ids, info, n, ESSCRIPT); } } } } /* ** Ident PC sounds */ static void IDENTdirPCSounds(ENTRY *ids,struct WADINFO *info,Bool Check) { Int16 n; ident_func = "IDENTdirPCSounds"; for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { if(info->dir[n].size>4) /*works only for DOOM, not HERETIC*/ if(strncmp(info->dir[n].name,"DP",2)==0) { if(Check==TRUE) { WADRseek(info,info->dir[n].start); if(WADRreadShort(info)==0x0) IDENTsetType (ids, info, n, ESNDPC); } } } } } /* * IDENTdirMusics */ static void IDENTdirMusics(ENTRY *ids,struct WADINFO *info,Bool Check) { Int16 n; ident_func = "IDENTdirMusics"; for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { /* Pre-4.4 method. Does not work for Hexen. When sure that the new method does not break merging and adding sprites and flats, delete this block and the -musid option. */ if (old_music_ident_method) { if (info->dir[n].size>8 && (strncmp(info->dir[n].name,"D_",2) == 0 || strncmp(info->dir[n].name,"MUS_",4) == 0)) { if (Check != TRUE) { IDENTsetType (ids, info, n, EMUSIC); } else { /* Must start with "MUS\x1a" */ WADRseek(info,info->dir[n].start); if (WADRreadShort(info)==0x554D && WADRreadShort(info)==0x1A53) IDENTsetType (ids, info, n, EMUSIC); } } } /* New method. Slower but more correct. */ else { if (info->dir[n].size >= 4) { WADRseek(info,info->dir[n].start); if (WADRreadShort(info)==0x554D && WADRreadShort(info)==0x1A53) { IDENTsetType (ids, info, n, EMUSIC); } } } } } } /* ** Ident sounds */ static void IDENTdirSounds(ENTRY *ids,struct WADINFO *info, Bool Doom) { Int16 n; ident_func = "IDENTdirSounds"; for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { if(info->dir[n].size>8) { /*works only for DOOM, not HERETIC*/ if(strncmp(info->dir[n].name,"DS",2)==0) { IDENTsetType (ids, info, n, ESNDWAV); } else if(Doom==FALSE) { WADRseek(info,info->dir[n].start); if(WADRreadShort(info)==0x3) if(WADRreadShort(info)==0x2B11) IDENTsetType (ids, info, n, ESNDWAV); } } } } } /* * IDENTdirLevels * This function is more complicated than I'd like it to be. */ static void IDENTdirLevels (ENTRY *ids, struct WADINFO *info) { Int16 n,l; char name[8]; char level_name[8]; ENTRY level=EVOID; /* int wrong_order = 0; */ const int part_num_max = IDENTlevelPartMax (); int in_level = 0; int lump_present[20]; /* Really sizeof Parts / sizeof *Parts */ char level_format = '\0'; /* Initialised to avoid a warning */ int n0 = 0; /* Initialised to avoid a warning */ ident_func = "IDENTdirLevels"; for (n = 0; n < info->ntry; n++) { Normalise (name,info->dir[n].name); if (! in_level) { if (ids[n] != EZZZZ) continue; l = IDENTlevel (name); if (l >= 0) { Normalise (level_name, info->dir[n].name); level = (*name == 'M') ? EMAP : ELEVEL; level |= l; n0 = n; lump_present[0] = 1; { int n; for (n = 1; n <= part_num_max; n++) lump_present[n] = 0; } /* Don't know whether it's Doom alpha or Doom/Heretic/Hexen/Strife yet. */ level_format = '?'; in_level = 1; } } else if (in_level) { int have_next = 0; char next_name[8]; int l_next = 0; /* Initialised to avoid a warning */ int p; int p_next = 0; /* Initialised to avoid a warning */ p = IDENTlevelPart (name); lump_present[p] = 1; if (Part[p].level_format != '?') level_format = Part[p].level_format; /* Was that the last lump of the level ? */ if (n + 1 < info->ntry && ids[n + 1] == EZZZZ) { have_next = 1; Normalise (next_name, info->dir[n + 1].name); l_next = IDENTlevel (next_name); p_next = IDENTlevelPart (next_name); } if (! have_next || l_next >= 0 || p_next < 0 || (Part[p_next].level_format != '?' && level_format != '?' && Part[p_next].level_format != level_format) || lump_present[p_next]) { in_level = 0; { int i; #if 0 for (i = 0; i <= max_lumps; i++) if (! lump_present[i] && Part[i].mandatory) Warning ("XX99", "Level %s: no %s lump", level_name, Part[i].name); #endif for (i = n0; i <= n; i++) IDENTsetType (ids, info, i, level); } } } #if 0 if(ids[n]==EZZZZ) { Normalise(name,info->dir[n].name); l=IDENTlevel(name); if(l>=0) { Normalise (level_name, info->dir[n].name); level=(name[0]=='M')? EMAP:ELEVEL; level|=l; level_lump = 1; IDENTsetType (ids, info, n, level); { int n; lump_present[0] = 1; for (n = 1; n <= max_lumps; n++) lump_present[n] = 0; wrong_order = 0; } } else if (level_lump > 0) { int l = IDENTlevelPart(name); if (have_lump[l]) { Warning ("XX99", "Level %s: duplicate %s lump", lump_name (level_name), lump_name (name)); level_lump = 0; } if (l != level_lump) { if (! wrong_order) Warning ("XX99", "Level %s: lumps in the wrong order (%s)", level_name, lump_name (name)); wrong_order = 1; } if (level_lump != 0) IDENTsetType (ids, info, n, level); /* If level is complete, stop here */ { int n; for (n = 0; n < max_lumps; n++) if (! lump_present[n]) break; if (n == max_lumps) level_lump = 0; } /* If end of directory or followed by other level, stop here */ if (n + 1 >= info->nentry) level_lump = 0; else { char next_lump[8]; if (n + 1 >= info->nentry || info->dir[n]); } } /* Reached last lump of level. */ if (level_lump == 0) { int n; for (n = 0; n <= max_lumps; n++) if (! have_lump[n] && IDENTlevelPartMandatory (n)) Warning ("XX99", "Level %s: no %s lump", IDENTlevelPartName (n)); } } "th ld sd v seg ss nod sec rej bm" "th ld sd v seg ss nod sec rej bm beh" "th ld sd v nod sec" "th ld sd v nod sec beh" "fn pnt lines sec th" #endif } if (in_level) Bug ("IL11", "Reached EOD while in level"); } /* ** IWAD: we assume all is correct ** if Fast = TRUE then sounds and most graphics are reported as lumps ** (this is for merge. no problem. bad identification only to be feared in PWAD) */ ENTRY *IDENTentriesIWAD (struct WADINFO *info,char *Pnam, Int32 Pnamsz, Bool Fast) { Int16 n; Bool Doom=FALSE; ENTRY *ids; Phase("ID50", "IWAD entry identification..."); if(info->ok!=TRUE)Bug("ID51", "IdnOeI"); ids=(ENTRY *)Malloc((info->ntry)*sizeof(ENTRY)); if(WADRfindEntry(info,"ENDTEXT")<0) /*Not Heretic*/ if(WADRfindEntry(info,"ENDOOM")>=0) Doom=TRUE; /* ** identify for IWAD */ for(n=0;nntry;n++) ids[n]=EZZZZ; IDENTdirLumps(ids,info); /*fast*/ IDENTdirSprites(ids,info,FALSE); /*fast*/ IDENTdirFlats(ids,info); /*fast*/ if (ROTT) IDENTdirWalls(ids,info); IDENTdirLevels(ids,info); /*fast*/ IDENTdirMusics(ids,info,FALSE); /*fast*/ IDENTdirPCSounds(ids,info,FALSE);/*fast*/ IDENTdirPatches(ids,info,Pnam,Pnamsz,FALSE); /*fast*/ IDENTdirGraphics(ids,info); /*fast*/ IDENTdirSscripts(ids,info); /* FIXME Should not be called if not Strife ! */ if(Fast!=TRUE) { IDENTdirSounds(ids,info,Doom); /*slow!*/ IDENTdirGraphics2(ids,info,TRUE);/*slow!*/ } /* unidentified entries are considered LUMPs*/ ident_func = "IDENTentriesIWAD"; for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { if(info->dir[n].size>=6) IDENTsetType (ids, info, n, ELUMP); else IDENTsetType (ids, info, n, EDATA); } } /* ** check registration */ /* switch(check) { case 1: case 2: break; default: ProgError("XX99", "please register your game"); } */ /*the end. WADR is still opened*/ return ids; } ENTRY *IDENTentriesPWAD(struct WADINFO *info,char *Pnam, Int32 Pnamsz) { Int16 n; ENTRY *ids; Phase("ID10", "PWAD entry identification..."); if(info->ok!=TRUE)Bug("ID11", "IdnOeP"); ids=(ENTRY *)Malloc((info->ntry)*sizeof(ENTRY)); /* ** identify for PWAD */ for(n=0;nntry;n++) ids[n]=EZZZZ; #ifdef DEBUG Phase("ID15", "Lumps..."); #endif IDENTdirLumps(ids,info); #ifdef DEBUG Phase("ID18", "Sprites..."); #endif IDENTdirSprites(ids,info,TRUE); #ifdef DEBUG Phase("ID21", "Flats..."); #endif IDENTdirFlats(ids,info); if (ROTT) { #ifdef DEBUG Phase ("ID24", "Walls..."); #endif IDENTdirWalls(ids,info); } #ifdef DEBUG Phase("ID27", "Levels..."); #endif IDENTdirLevels(ids,info); #ifdef DEBUG Phase("ID30", "Musics..."); #endif IDENTdirMusics(ids,info,TRUE); #ifdef DEBUG Phase("ID33", "PCsnd..."); #endif IDENTdirPCSounds(ids,info,TRUE); #ifdef DEBUG Phase("ID36", "Patches..."); #endif IDENTdirPatches(ids,info,Pnam,Pnamsz,TRUE); #ifdef DEBUG Phase("ID39", "Graphics(1)..."); #endif IDENTdirGraphics(ids,info); #ifdef DEBUG Phase("ID42", "Scripts..."); #endif IDENTdirSscripts(ids,info); /* FIXME Should not be called if not Strife ! */ #ifdef DEBUG Phase("ID45", "Sounds..."); #endif IDENTdirSounds(ids,info,FALSE); #ifdef DEBUG Phase("ID48", "Graphics(2)..."); #endif IDENTdirGraphics2(ids,info,TRUE); ident_func = "IDENTentriesPWAD"; for(n=0;nntry;n++) { if(ids[n]==EZZZZ) { if(info->dir[n].size>16) IDENTsetType (ids, info, n, ELUMP); else IDENTsetType (ids, info, n, EDATA); } } /* ** unidentified entries are considered LUMPs */ /*the end. WADR is still opened*/ return ids; } /* * entry_type_name * Return human-readable string for numeric entry type */ typedef struct { ENTRY type; const char *name; const char *plural; PICTYPE pictype; } entry_type_def_t; static const entry_type_def_t entry_type_def[] = { { EVOID, "label", "labels", -1 }, { ELEVEL, "level(ExMy)", "levels", -1 }, { EMAP, "level(MAPxy)", "levels", -1 }, { ELUMP, "lump", "lumps", PLUMP }, { ETEXTUR, "texture", "textures", -1 }, { EPNAME, "pname", "pnames", -1 }, { ESOUND, "sound", "sounds", -1 }, { EGRAPHIC, "graphics", "graphics", PGRAPH }, { ESPRITE, "sprite", "sprites", PSPRIT }, { EPATCH, "patch", "patches", PPATCH }, { EFLAT, "flat", "flats", PFLAT }, { EMUSIC, "music", "musics", -1 }, { EDATA, "data", "datas", -1 }, /* Counting sheeps */ { ESNEA, "snea", "sneas", -1 }, { ESNEAP, "sneap", "sneaps", PSNEAP }, { ESNEAT, "sneat", "sneats", PSNEAT }, { ESSCRIPT, "script", "scripts", -1 }, { EWALL, "wall", "walls", PWALL }, { 0, NULL, NULL, -1 } }; static ENTRY last_type = -1; static const entry_type_def_t *last_def = NULL; static const entry_type_def_t *get_entry_type_def (ENTRY type) { const entry_type_def_t *p; if (type == last_type) return last_def; for (p = entry_type_def; p->name != NULL; p++) if (p->type == type) { last_type = type; last_def = p; return p; } for (p = entry_type_def; p->name != NULL; p++) if (p->type == (type & EMASK)) { last_type = type; last_def = p; return p; } return NULL; } const char *entry_type_name (ENTRY type) { const entry_type_def_t *def = get_entry_type_def (type); if (def == NULL) return "(unknown)"; else return def->name; } const char *entry_type_plural (ENTRY type) { const entry_type_def_t *def = get_entry_type_def (type); if (def == NULL) return "(unknown)"; else return def->plural; } const char *entry_type_dir (ENTRY type) { return entry_type_plural (type); } const char *entry_type_section (ENTRY type) { return entry_type_plural (type); } PICTYPE entry_type_pictype (ENTRY type) { const entry_type_def_t *def = get_entry_type_def (type); if (def == NULL) return -1; else return def->pictype; } /***************end IDENT module *******************/ deutex-4.4.902/src/listdir.c0000644000324500032450000004237410305323106015200 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include "tools.h" #include "endianm.h" #include "mkwad.h" #include "texture.h" #include "ident.h" extern char file[128]; /* ** list WAD directory and identify entries */ static char *Views[] = {"?","All ", "Front","FrRgt","Right","RrRgt", "Rear ","RrLft","Left ","FrLft"}; static char *IdentView(char view) { switch(view) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': return Views[1+view-'0']; } return Views[0]; } /* * XTRlistDir - implementation of -wadir */ void XTRlistDir(const char *doomwad, const char *wadin, NTRYB select) { Int16 n; static struct WADINFO pwad; static struct WADINFO iwad; static char buffer[128]; ENTRY *iden; ENTRY type; Int32 ntry; struct WADDIR *dir; char *typ; Int16 pnm;char *Pnam;Int32 Pnamsz=0; /*open iwad,get iwad directory*/ iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES*/ pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) ProgError("LS10", "Can't find PNAMES in main WAD"); Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz); WADRclose(&iwad); /**/ if(wadin!=NULL) { pwad.ok=0; WADRopenR(&pwad,wadin); iden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz); ntry= pwad.ntry; dir= pwad.dir; } else { iwad.ok=0; WADRopenR(&iwad,doomwad); iden=IDENTentriesIWAD(&iwad, Pnam, Pnamsz,FALSE); ntry= iwad.ntry; dir= iwad.dir; } /**/ Free(Pnam); /**/ Output("\nListing of WAD directory for %s\n\n", wadin != NULL ? wadin : doomwad); Output("Entry\t Size\tType\n\n"); for(n=0;n>4),'0'+(type&0xF)); typ=buffer; break; case EMAP: sprintf(buffer,"Level Map %d",(type&0xFF)); typ=buffer; break; case ETEXTUR: typ = "List of textures"; break; case EPNAME: typ = "List of patches"; break; case ESOUND: typ = "Sound"; break; case EMUSIC: typ = "Music"; break; case EGRAPHIC: if((type&0xFF)==0xFF) { typ="Graphic"; } else { sprintf(buffer,"Graphic"); typ=buffer; } break; case ELUMP: typ = "Lump of raw data"; break; case ESPRITE: typ = "Sprite"; if(strncmp(dir[n].name,"ARTI",4)==0) { sprintf(buffer,"Artifact\t%4.4s",&(dir[n].name[4])); } else if(dir[n].name[6]!='\0') { sprintf(buffer,"Sprite %4.4s\tph:%c %s\tph:%c %s inv.", dir[n].name, dir[n].name[4], IdentView(dir[n].name[5]), dir[n].name[6], IdentView(dir[n].name[7])); } else { sprintf(buffer,"Sprite %4.4s\tph:%c %s", dir[n].name, dir[n].name[4], IdentView(dir[n].name[5])); } typ = buffer; break; case EPATCH: typ = "Patch"; break; case EFLAT: typ = "Flat"; break; case EZZZZ: typ = "?"; break; } switch(type) { case EPATCH1: typ = "Patch 1"; break; case EPATCH2: typ = "Patch 2"; break; case EPATCH3: typ = "Patch 3"; break; case EFLAT1: typ = "Flat 1"; break; case EFLAT2: typ = "Flat 2"; break; case EFLAT3: typ = "Flat 3"; break; case ESNDPC: typ = "PC sound"; break; case ESNDWAV: typ = "WAV sound"; break; } Output("%-8s %8ld\t%s\n", lump_name (dir[n].name), dir[n].size, typ); } if(wadin!=NULL) WADRclose(&pwad); else WADRclose(&iwad); Free(iden); } #if defined(DeuTex) #if DT_OS == 'o' # if DT_CC = 'b' int _USERENTRY XTRdirCmp(const void *d1,const void *d2) # else int _Optlink XTRdirCmp(const void *d1,const void *d2) # endif #else int XTRdirCmp(const void *d1,const void *d2) #endif { Int32 res; struct WADDIR *dir1=(struct WADDIR *)d1; struct WADDIR *dir2=(struct WADDIR *)d2; res= (dir1->start)-(dir2->start); if(res<0)return -1; if(res>0)return 1; res = (dir1->size)-(dir2->size); if(res<0)return -1; if(res>0)return 1; return 0; } void XTRvoidSpacesInWAD(const char *wadin) { Int16 n; static struct WADINFO pwad; Int32 ntry; struct WADDIR *dir; Int32 startpos,lastpos,ll,diff,wtotal; Int32 w3,w20,w100,w1000,w10000,w100000; wtotal=w3=w20=w100=w1000=w10000=w100000=0; pwad.ok=0; WADRopenR(&pwad,wadin); ntry= pwad.ntry; dir= pwad.dir; qsort(dir,(size_t)ntry,sizeof(struct WADDIR),XTRdirCmp); Output("\nListing of unused spaces in WAD %s\n",wadin); lastpos=4+4+4; for(n=0;n=4) /*suppress word alignement*/ Output(" At offset 0x%8.8lx, %ld bytes wasted\n",startpos,diff); } Output("\nRepartition of wasted bytes:\n"); Output(" All blocks<=3 \t%ld\n",w3); Output(" All blocks<=20 \t%ld\n",w20); Output(" All blocks<=100 \t%ld\n",w100); Output(" All blocks<=1000 \t%ld\n",w1000); Output(" All blocks<=10000\t%ld\n",w10000); Output(" All blocks> 10000\t%ld\n",w100000); Output(" \t-------\n"); Output(" Total wasted bytes\t%ld\n",wtotal); WADRclose(&pwad); } #endif struct SIDEDEF { Int16 ofsx; /* X offset for texture */ Int16 ofsy; /* Y offset for texture */ char Above[8]; /* texture name for the part above */ char Below[8]; /* texture name for the part below */ char Center[8]; /* texture name for the regular part */ Int16 Sector; /* adjacent sector */ }; /* ** Check a level ** Assumes TEXTURES are already read somewhere. */ void CheckTexture(char *tex,Bool IsDef) { int n; char Name[8]; for(n=0;n<8;n++) { Name[n]=tex[n]; if(tex[n]=='\0')break; } Normalise(Name,Name); switch(Name[0]) { case '-': case '\0': break; default: if(IsDef==TRUE) /*if we only wish to declare the tex*/ { TXUfakeTex(Name); } else { if(TXUexist(Name)==FALSE) Output("Warning: undefined sidedef %s\n", lump_name (Name)); } } } /* **check textures ** IsDef=TRUE if we just wish to declare textures */ void CheckSideDefs(struct WADINFO *pwad,Int32 start,Int32 size,Bool IsDef) { struct SIDEDEF *sid; struct SIDEDEF *side; Int32 s; sid = (struct SIDEDEF *)Malloc(size); WADRseek(pwad,start); WADRreadBytes(pwad,(char *)sid,size); for(s=0;(s*sizeof(struct SIDEDEF))Above,IsDef); CheckTexture(side->Below,IsDef); CheckTexture(side->Center,IsDef); } Free(sid); } void CheckLevels(struct WADINFO *pwad, Bool IsDef) { Int16 lev,lin,id,top; Int32 ntry=pwad->ntry; struct WADDIR *pdir=pwad->dir; for(lev=0;lev=0) { for(lin=lev;lintop) break; if(strncmp(pdir[lin].name,"SIDEDEFS",8)==0) { Output("\nChecking LEVEL %s\n\n", lump_name (pdir[lev].name)); CheckSideDefs(pwad,pdir[lin].start,pdir[lin].size,IsDef); } } } } } /* ** Test a PWAD (-check) ** ** this is absolutely sub optimal. */ void XTRstructureTest(const char *doomwad,const char *wadin) { static struct WADINFO pwad,iwad; char *Pnames; Int16 p,pnm,nbPatchs; Int32 size; static struct PICH{Int16 Xsz;Int16 Ysz;} pich; Int16 *PszX; static char name[8]; char *buffer; Int16 cs,ce; /*read PNAME in wad, if defined*/ Phase("LS21", "Reading WADs"); iwad.ok=0; WADRopenR(&iwad,doomwad); pwad.ok=0; WADRopenR(&pwad,wadin); Phase("LS23", "Reading Patches"); pnm=WADRfindEntry(&pwad,"PNAMES"); if(pnm>=0) { size=pwad.dir[pnm].size; Pnames=(char *)Malloc(size); WADRseek(&pwad,pwad.dir[pnm].start); WADRreadBytes(&pwad,Pnames,size); } else { pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0)ProgError("LS25", "PNAMES not found"); size=iwad.dir[pnm].size; Pnames=(char *)Malloc(size); WADRseek(&iwad,iwad.dir[pnm].start); WADRreadBytes(&iwad,Pnames,size); } PNMinit(Pnames,size); Free(Pnames); /* ** find each PNAME and identify Xsz Ysz */ Phase("LS27", "Checking Patches"); nbPatchs=PNMgetNbOfPatch(); PszX=(Int16 *)Malloc(nbPatchs*sizeof(Int16)); for(p=0;p=0) { WADRseek(&pwad,pwad.dir[pnm].start); WADRreadBytes(&pwad,(char *)&pich,sizeof(struct PICH)); } else { pnm=WADRfindEntry(&iwad,name); if(pnm<0) Output("Warning: Patch %s not found\n", lump_name (name)); else { WADRseek(&iwad,iwad.dir[pnm].start); WADRreadBytes(&iwad,(char *)&pich,sizeof(struct PICH)); } } PszX[p] = peek_i16_le (&pich.Xsz); } /* ** read TEXTURES */ Phase("LS29", "Reading Textures"); pnm=WADRfindEntry(&pwad,"TEXTURE1"); if(pnm>=0) { /* read texture */ const struct WADDIR *e = pwad.dir + pnm; buffer=(char *)Malloc(e->size); WADRseek(&pwad,e->start); WADRreadBytes(&pwad,buffer,e->size); TXUinit(); TXUreadTEXTURE(e->name, buffer, e->size, NULL, 0, TRUE); Free(buffer); /*for each textures, check what is covered */ Phase("LS31", "Checking TEXTURE1"); TXUcheckTex(nbPatchs,PszX); TXUfree(); } pnm=WADRfindEntry(&pwad,"TEXTURE2"); if(pnm>=0) { /* read texture */ const struct WADDIR *e = pwad.dir + pnm; buffer=(char *)Malloc(e->size); WADRseek(&pwad,e->start); WADRreadBytes(&pwad,buffer,e->size); TXUinit(); TXUreadTEXTURE(e->name, buffer, e->size, NULL, 0, TRUE); Free(buffer); /*for each textures, check what is covered */ Phase("LS33", "Checking TEXTURE2"); TXUcheckTex(nbPatchs,PszX); TXUfree(); } Free(PszX); /* ** check if all textures composing walls are here ** */ Phase("LS35", "Checking Level SIDEDEFS for missing textures"); TXUinit(); pnm=WADRfindEntry(&pwad,"TEXTURE1"); if(pnm>=0) { const struct WADDIR *e = pwad.dir + pnm; buffer=(char *)Malloc(e->size); WADRseek(&pwad,e->start); WADRreadBytes(&pwad,buffer,e->size); TXUreadTEXTURE(e->name, buffer, e->size, NULL, 0, TRUE); Free(buffer); } else { pnm = WADRfindEntry(&iwad,"TEXTURE1"); if(pnm>=0) { const struct WADDIR *e = iwad.dir + pnm; buffer=(char *)Malloc(e->size); WADRseek(&iwad,e->start); WADRreadBytes(&iwad,buffer,e->size); TXUreadTEXTURE(e->name, buffer, e->size, NULL, 0, TRUE); Free(buffer); } } pnm=WADRfindEntry(&pwad,"TEXTURE2"); if(pnm>=0) { const struct WADDIR *e = pwad.dir + pnm; buffer=(char *)Malloc(e->size); WADRseek(&pwad,e->start); WADRreadBytes(&pwad,buffer,e->size); TXUreadTEXTURE(e->name, buffer, e->size, NULL, 0, TRUE); Free(buffer); } else { pnm = WADRfindEntry(&iwad,"TEXTURE2"); if(pnm>=0) { const struct WADDIR *e = iwad.dir + pnm; buffer=(char *)Malloc(e->size); WADRseek(&iwad,e->start); WADRreadBytes(&iwad,buffer,e->size); TXUreadTEXTURE(e->name, buffer, e->size, NULL, 0, TRUE); Free(buffer); } } CheckLevels(&pwad,FALSE); TXUfree(); PNMfree(); WADRclose(&iwad); /* ** check sprite markers ** */ Phase("LS37", "Checking Sprites"); for(cs=ce=0,p=0;p1) ProgError("LS39", "Duplicate S_START"); if(ce>1) ProgError("LS41", "Duplicate S_END"); if((cs>0)&(ce<1)) Output("Warning: S_START but no S_END\n"); if((cs<1)&(ce<1)) Info("LS43", "No need to check sprites"); else { for(cs=ce=0,p=0;p1) Output("Warning: Duplicate F_START\n"); if(ce>1) Output("Warning: Duplicate F_END\n"); if((cs>0)&(ce<1)) Output("Warning: F_START but no F_END\n"); if((cs<1)&(ce<1))Info("LS47", "No need to check flats"); WADRclose(&pwad); } #if defined(DeuTex) /* ** Test a PWAD (-usedtex) ** */ void XTRtextureUsed(const char *wadin) { static struct WADINFO pwad; /*read PNAME in wad, if defined*/ Phase("LS50", "Listing texture used in the levels of %s", fname (wadin)); pwad.ok=0; WADRopenR(&pwad,wadin); /* ** list all textures composing walls */ TXUinit(); CheckLevels(&pwad,TRUE); Output("List of textures used in %s\n\n",wadin); TXUlistTex(); TXUfree(); WADRclose(&pwad); } #endif #if defined(DeuTex) /* ** Detect duplicate entries (-packgfx, -packnorm) ** ShowIdx = TRUE if we also output the indexes ** ** Optimise for speed with a CRC-based check */ void XTRcompakWAD(const char *DataDir,const char *wadin, const char *texout, Bool ShowIdx) { static struct WADINFO pwad; struct WADDIR *pdir; Int16 pnb; Int16 p,bas,tst,ofsx,ofsy; Int32 size,rsize,sz; Bool *psame; FILE *out; char *bbas; char *btst; Phase("LS60", "Detecting duplicate entries in WAD %s", fname (wadin)); pwad.ok=0; WADRopenR(&pwad,wadin); pnb=(Int16)pwad.ntry; pdir=pwad.dir; psame=(Bool *)Malloc(pnb*sizeof(Bool)); for(p=0;p=8)&&(ShowIdx==TRUE)) { WADRseek(&pwad,pdir[bas].start); WADRreadBytes(&pwad,bbas,8); ofsx=((bbas[5]<<8)&0xFF00)+(bbas[4]&0xFF); ofsy=((bbas[7]<<8)&0xFF00)+(bbas[6]&0xFF); fprintf(out,"%-8.8s\t%d\t%d\n",pdir[bas].name,ofsx,ofsy); } else fprintf(out,"%-8.8s\n",pdir[bas].name); for(tst=bas+1;tstMEMORYCACHE)? MEMORYCACHE : size-rsize; WADRseek(&pwad,pdir[bas].start+rsize); WADRreadBytes(&pwad,bbas,sz); WADRseek(&pwad,pdir[tst].start+rsize); WADRreadBytes(&pwad,btst,sz); for(p=0;p=0;l--) { if(strncmp(LISspr.Lst[l].name,root,4)==0) { /*2nd unwanted: replace by 0*/ if(LISunwantedPhase(&(LISspr.Lst[l].name[6]),phase,view,AllViews)==TRUE) { LISspr.Lst[l].name[6]='\0'; LISspr.Lst[l].name[7]='\0'; Okay=TRUE; } /*1st unwanted: replace by second*/ if(LISunwantedPhase(&(LISspr.Lst[l].name[4]),phase,view,AllViews)==TRUE) { LISspr.Lst[l].name[4]=LISspr.Lst[l].name[6]; LISspr.Lst[l].name[5]=LISspr.Lst[l].name[7]; LISspr.Lst[l].name[6]='\0'; LISspr.Lst[l].name[7]='\0'; Okay=TRUE; } /*neither 1st nor second wanted: delete*/ if(LISspr.Lst[l].name[4]=='\0') { sz=LISspr.Pos-(l+1); if(sz>0) Memcpy(&(LISspr.Lst[l]),&(LISspr.Lst[l+1]),(sz)*sizeof(struct WADDIR)); LISspr.Pos--; Okay=TRUE; } } } return Okay; } /* ** list management. very basic. no hash table. */ static void LISaddMission(struct WADDIR *dir, Int16 found) { Int16 l=0,dummy=0; /*check*/ if(LISlmp.Pos>=LISlmp.Top) Bug("LI03", "LisTsm"); /*level list too small*/ /*try to locate mission entry at l*/ for(l=0;lLISlmp.Pos) LISlmp.Pos=dummy; if(LISlmp.Pos>LISlmp.Top) Bug("LI05", "LisTsm"); /*level list too small*/ /*copy new level, or replace existing*/ Memcpy((&(LISlmp.Lst[l])),(dir),found*sizeof(struct WADDIR)); } static void LISadd(struct ELIST *L,struct WADDIR *dir) { /*check current position*/ if((L->Pos)>=L->Top) Bug("LI07", "LisSml"); /*list count too small*/ /* ADD in List */ Memcpy(&(L->Lst[(L->Pos)]),(dir),sizeof(struct WADDIR)); (L->Pos)++; /*increase pointer in list*/ return; } /* ** Find in list, and replace if exist ** */ static Bool LISfindRplc(struct ELIST *L,struct WADDIR *dir) { Int16 l; for(l=0;l<(L->Pos);l++) if(strncmp(L->Lst[l].name,dir[0].name,8)==0) { Memcpy(&(L->Lst[l]),&(dir[0]),sizeof(struct WADDIR)); return TRUE; } return FALSE; /*not found*/ } /* Substitute In List ** if entry exist, it is substituted, else added at the end of list ** suitable for LUMPS and SPRITES ** but generally those shall not be added: they may not be recognized */ static void LISsubstit(struct ELIST *L,struct WADDIR *dir) { /* SUBSTIT in List */ if(LISfindRplc(L,dir)==TRUE) return; Warning("LI09", "Entry %s might be ignored by the game", lump_name (dir[0].name)); LISadd(L,dir); } /* Move In List ** if entry already exist, destroy it, and put at the end ** suitable for PATCH and FLATS (to define new animations) */ static void LISmove(struct ELIST *L,struct WADDIR *dir) { Int16 l,sz; for(l=0;l<(L->Pos);l++) if(strncmp(L->Lst[l].name,dir[0].name,8)==0) { /*entry already exist. destroy it*/ sz=(L->Pos)-(l+1); if(sz>0) Memcpy(&(L->Lst[l]),&(L->Lst[l+1]),(sz)*sizeof(struct WADDIR)); (L->Pos)--; } LISadd(L,dir); } /* Put Sprites In List ** if entry already exist, replace it ** if entry does not exist, check if it does not obsolete ** an IWAD sprite entry ** suitable for SPRITES only */ /***/ static void LISaddSprite(struct WADDIR *dir,Bool Warn) { Bool Okay=FALSE; /*warn: FALSE= no warning. TRUE = warn.*/ /* If entry already exists, replace it*/ if(LISfindRplc(&LISspr,dir)==TRUE) return; /* Entry does not exist. Check that this sprite ** viewpoint doesn't obsolete other sprite viewpoints. */ if(dir[0].name[4]!='\0') { Okay|=LISdeleteSprite(dir[0].name,dir[0].name[4],dir[0].name[5]); if(dir[0].name[6]!='\0') Okay|=LISdeleteSprite(dir[0].name,dir[0].name[6],dir[0].name[7]); } if((Okay==FALSE)&&(Warn==TRUE)) { Warning("LI11", "Entry %s might be ignored by the game", lump_name (dir[0].name)); } LISadd(&LISspr,dir); } /* ** create a new directory list ** */ static void LISmakeNewDir(struct WADINFO *nwad,Int16 S_END,Int16 P_END,Int16 F_END,Int16 Pn,Int16 Fn) { Int16 n; struct WADDIR *dir; /*levels,lumps, graphics into new dir*/ if(LISlmp.Pos>0) { for(n=0;nstart,dir->size,dir->name); } } /*sprites into new dir*/ if(LISspr.Pos>0) { WADRdirAddPipo(nwad,0,0,((S_END & X_START)? "S_START":"SS_START")); for(n=0;nstart,dir->size,dir->name); } WADRdirAddPipo(nwad,0,0,((S_END & X_END)? "S_END":"SS_END")); } /*patch 1,2,3 into new dir*/ if(LISpat.Pos>0) { WADRdirAddPipo(nwad,0,0,((P_END & X_START)?"P_START":"PP_START")); if((Pn>=1)&&(P_END & X_START)) WADRdirAddPipo(nwad,0,0,"P1_START"); for(n=0;nstart,dir->size,dir->name); } if((Pn>=1)&&(P_END & X_START)) { WADRdirAddPipo(nwad,0,0,"P1_END"); if(Pn>=2) { WADRdirAddPipo(nwad,0,0,"P2_START"); WADRdirAddPipo(nwad,0,0,"P2_END"); if(Pn>=3) { WADRdirAddPipo(nwad,0,0,"P3_START"); WADRdirAddPipo(nwad,0,0,"P3_END"); } } } WADRdirAddPipo(nwad,0,0,((P_END & X_END)?"P_END":"PP_END")); } /*flat 1,2,3 into new dir*/ if(LISflt.Pos>0) { WADRdirAddPipo(nwad,0,0,((F_END & X_START)?"F_START":"FF_START")); if((Fn>=1)&&(F_END & X_START)) WADRdirAddPipo(nwad,0,0,"F1_START"); for(n=0;nstart,dir->size,dir->name); } if((Fn>=1)&&(F_END & X_START)) { WADRdirAddPipo(nwad,0,0,"F1_END"); if(Fn>=2) { WADRdirAddPipo(nwad,0,0,"F2_START"); WADRdirAddPipo(nwad,0,0,"F2_END"); if(Fn>=3) { WADRdirAddPipo(nwad,0,0,"F3_START"); WADRdirAddPipo(nwad,0,0,"F3_END"); } } } WADRdirAddPipo(nwad,0,0,((F_END & X_END)?"F_END":"FF_END")); } } /* ** merge IWAD and PWAD directories ** This function is a good example of COMPLETELY INEFFICIENT CODING. ** but since it's so hard to have it work correctly, ** Optimising was out of question. ** ** */ struct WADDIR *LISmergeDir(Int32 *pNtry,Bool Append,Bool Complain,NTRYB select, struct WADINFO *iwad,ENTRY *iiden,Int32 iwadflag, struct WADINFO *pwad,ENTRY *piden,Int32 pwadflag) { struct WADDIR *idir; struct WADDIR *pdir; struct WADINFO nwad; Int16 inb, pnb; Int16 i,p,found; struct WADINFO *refwad; ENTRY type; Int16 Pn=0;/*0=nothing 1=P1_ 2=P2_ 3=P3_*/ Int16 Fn=0;/*0=nothing 1=F1_ 2=F2_ 3=F3_*/ Bool NoSprite=FALSE; /*no sprites declared. seek in graphics*/ Int16 S_END=X_NONE; Int16 F_END=X_NONE; Int16 P_END=X_NONE; /* ** select Sprites markers (tricky hack!) */ refwad = ((Append!=TRUE)||(select&BSPRITE))? iwad : pwad; if(WADRfindEntry(refwad,"S_END")>=0)/*full sprite list is here*/ { S_END|=X_END; } if(WADRfindEntry(refwad,"S_START")>=0)/*full sprite list is here*/ { S_END|=X_START; } if(!(select&BSPRITE)) { if(S_END & X_END) /*sprites already appended. keep it so.*/ { Complain=FALSE; } } /* ** select Patches markers (tricky hack!) */ refwad = (Append!=TRUE)? iwad : pwad; if(WADRfindEntry(refwad,"P_END")>=0)/*full patch list is here*/ { P_END|=X_END; if(WADRfindEntry(refwad,"P3_END")>=0) Pn=3; else if(WADRfindEntry(refwad,"P2_END")>=0) Pn=2; else if(WADRfindEntry(refwad,"P1_END")>=0) Pn=1; } if(WADRfindEntry(refwad,"P_START")>=0)/*full patch list is here*/ { P_END|=X_START; } /* ** select Flats markers (tricky hack!) */ refwad = ((Append!=TRUE)||(select&BFLAT))? iwad : pwad; if(WADRfindEntry(refwad,"F_END")>=0) /*full flat list is here*/ { F_END|=X_END; if(WADRfindEntry(refwad,"F3_END")>=0) Fn=3; else if(WADRfindEntry(refwad,"F2_END")>=0) Fn=2; else if(WADRfindEntry(refwad,"F1_END")>=0) Fn=1; } if(WADRfindEntry(refwad,"F_START")>=0) /*full flat list is here*/ { F_END|=X_START; } if(!(select&BFLAT)) { if(F_END & X_END) /*flats already appended. keep it so.*/ { Complain=FALSE; } } /* ** make lists of types lists */ inb= (Int16)iwad->ntry; pnb= (Int16)pwad->ntry; idir=iwad->dir; pdir=pwad->dir; /*alloc memory for a fake new wad*/ nwad.ok=0; WADRopenPipo(&nwad,(Int32)inb+(Int32)pnb+40); /*init lists*/ LISinitLists(); /*identify the elements and count types*/ LIScountTypes(iiden,(Int16)iwad->ntry); LIScountTypes(piden,(Int16)pwad->ntry); LISallocLists(); /* distribute IWAD enties*/ for(i=0;i #include #include "deutex.h" #include "log.h" #include "tools.h" static FILE *logfp = NULL; static FILE nolog; /* * lopen - open the log file if necessary * * Return 0 if logfp can be written to, non-zero otherwise. */ int lopen (void) { if (logfp == &nolog) return 1; if (logfp == NULL) { logfp = fopen (logfile, "w"); if (logfp == NULL) { /* Can't use Warning(), we would loop. */ fflush (stdout); fprintf (stderr, "%c LG10 %s: %s\n", MSGCLASS_WARN, logfile, strerror (errno)); logfp = &nolog; return 1; } } return 0; } /* No lclose(). Bah. */ /* * lputc - write a character into the log file */ void lputc (char c) { if (logfp == NULL) return; fputc (c, logfp); fflush (logfp); /* We don't want a segfault to truncate the log */ } /* * lputs - write a string into the log file */ void lputs (const char *str) { if (logfp == NULL) return; fputs (str, logfp); fflush (logfp); /* We don't want a segfault to truncate the log */ } /* * lprintf - printf into the log file */ void lprintf (const char *fmt, ...) { va_list list; if (logfp == NULL) return; va_start (list, fmt); vlprintf (fmt, list); va_end (list); } /* * vlprintf - vprintf into the log file */ void vlprintf (const char *fmt, va_list list) { if (logfp == NULL) return; vfprintf (logfp, fmt, list); fflush (logfp); /* We don't want a segfault to truncate the log */ } deutex-4.4.902/src/lzw.c0000644000324500032450000004043507032764266014361 0ustar aymaym00000000000000/* +-------------------------------------------------------------------+ */ /* | Copyright 1993, David Koblas (koblas@netcom.com) | */ /* | | */ /* | Permission to use, copy, modify, and to distribute this software | */ /* | and its documentation for any purpose is hereby granted without | */ /* | fee, provided that the above copyright notice appear in all | */ /* | copies and that both that copyright notice and this permission | */ /* | notice appear in supporting documentation. There is no | */ /* | representations about the suitability of this software for | */ /* | any purpose. this software is provided "as is" without express | */ /* | or implied warranty. | */ /* | | */ /* +-------------------------------------------------------------------+ */ /* ** This file is derived from ppmtogif.c and giftoppm.c ** only the compression/decompression routines were kept. ** ** Based on GIFENCOD by David Rowley .A ** Lempel-Zim compression based on "compress". ** ** Copyright (C) 1989 by Jef Poskanzer. ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. ** ** The Graphics Interchange Format(c) is the Copyright property of ** CompuServe Incorporated. GIF(sm) is a Service Mark property of ** CompuServe Incorporated. ** ** This coder is included in DeuTex only because that of David Kaplan ** didn't work ** */ #include "deutex.h" #include "tools.h" /*compile only for DeuTex*/ #if defined DeuTex #if NEWGIFE && NEWGIFD /*nothing, for new gif encoder*/ #else /* * General DEFINEs */ #define BITS 12 #define HSIZE 5003 /* 80% occupancy */ typedef char char_type; typedef Int16 code_int; /* 2**BITS values of type int, and also -1 */ typedef Int32 count_int; /*static Int16 table[2][(1< #if NEWGIFE #else static Int16 n_bits; /* number of bits/code */ static Int16 maxbits; /* user settable max # bits/code */ static code_int maxcode; /* maximum code, given n_bits */ static code_int maxmaxcode; /* should NEVER generate this code */ # define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1) #define HashTabOf(i) htab[i] #define CodeTabOf(i) codetab[i] static code_int hsize; /* for dynamic table sizing */ static UInt32 cur_accum; static Int16 cur_bits; /* * To save much memory, we overlay the table used by compress() with those * used by decompress(). The tab_prefix table is the same size and type * as the codetab. The tab_suffix table needs 2**BITS characters. We * get this from the beginning of htab. The output stack uses the rest * of htab, and contains characters. There is plenty of room for any * possible stack (stack used to be 8000 characters). */ #define tab_prefixof(i) CodeTabOf(i) #define tab_suffixof(i) ((char_type*)(htab))[i] #define de_stack ((char_type*)&tab_suffixof((code_int)1< 0 ) goto probe; nomatch: output ( (code_int) ent ); out_count++; ent = c; if ( free_ent < maxmaxcode ) { CodeTabOf (i) = free_ent++; /* code -> hashtable */ HashTabOf (i) = fcode; } else cl_block(); } /* * Put out the final code. */ output( (code_int)ent ); ++out_count; output( (code_int) EOFCode ); } /***************************************************************** * TAG( output ) * * Output the given code. * Inputs: * code: A n_bits-bit integer. If == -1, then EOF. This assumes * that n_bits =< (Int32)wordsize - 1. * Outputs: * Outputs code to the file. * Assumptions: * Chars are 8 bits Int32. * Algorithm: * Maintain a BITS character long buffer (so that 8 codes will * fit in it exactly). Use the VAX insv instruction to insert each * code in turn. When the buffer fills up empty it and start over. */ static UInt32 masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; static void output( code_int code) { cur_accum &= masks[ cur_bits ]; if( cur_bits > 0 ) cur_accum |= ((Int32)code << cur_bits); else cur_accum = code; cur_bits += n_bits; while( cur_bits >= 8 ) { char_out( (UInt16)(cur_accum & 0xff) ); cur_accum >>= 8; cur_bits -= 8; } /* * If the next entry is going to be too big for the code size, * then increase it, if possible. */ if ( free_ent > maxcode || clear_flg ) { if( clear_flg ) { maxcode = (code_int)(MAXCODE (n_bits = g_init_bits)); clear_flg = 0; } else { n_bits++; if ( n_bits == maxbits ) maxcode = maxmaxcode; else maxcode = (code_int)(MAXCODE(n_bits)); } } if( code == EOFCode ) { /* At EOF, write the rest of the buffer.*/ while( cur_bits > 0 ) { char_out( (UInt16)(cur_accum & 0xff) ); cur_accum >>= 8; cur_bits -= 8; } flush_char(); fflush( g_outfile ); } } /* * Clear out the hash table */ static void cl_block () /* table clear for block compress */ { cl_hash ( (count_int) hsize ); free_ent = (code_int)(ClearCode + 2); clear_flg = 1; output( (code_int)ClearCode ); } static void cl_hash(register count_int hsize) /* reset code table */ { count_int *htab_p = htab+(int)hsize; register Int32 i; register Int32 m1 = -1; i = hsize - 16; do { /* might use Sys V memset(3) here */ *(htab_p-16) = m1; *(htab_p-15) = m1; *(htab_p-14) = m1; *(htab_p-13) = m1; *(htab_p-12) = m1; *(htab_p-11) = m1; *(htab_p-10) = m1; *(htab_p-9) = m1; *(htab_p-8) = m1; *(htab_p-7) = m1; *(htab_p-6) = m1; *(htab_p-5) = m1; *(htab_p-4) = m1; *(htab_p-3) = m1; *(htab_p-2) = m1; *(htab_p-1) = m1; htab_p -= 16; } while ((i -= 16) >= 0); for ( i += 16; i > 0; --i ) *--htab_p = m1; } /****************************************************************************** * * GIF Specific routines * ******************************************************************************/ /* * Number of characters so far in this 'packet' */ static Int16 a_count; /* * Set up the 'byte output' routine */ static void char_init() { a_count = 0; } /* * Define the storage for the packet accumulator */ static char accum[ 256 ]; /* * Add a character to the end of the current packet, and if it is 254 * characters, flush the packet to disk. */ static void char_out( Int16 c) { accum[ a_count++ ] = (char)c; if( a_count >= 254 ) flush_char(); } /* * Flush the packet to disk, and reset the accumulator */ static void flush_char() { if( a_count > 0 ) { fputc( a_count, g_outfile ); fwrite( accum, 1, a_count, g_outfile ); a_count = 0; } } #endif /*NEWGIFE*/ /* The End */ /* ** ** Gif decompression ** */ #if NEWGIFD #else #define TRUE 1 #define FALSE 0 #define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) == 1) static Int16 ZeroDataBlock = FALSE; Int16 GetDataBlock(FILE *fd, unsigned char *buf) { unsigned char count; if (! ReadOK(fd,&count,1)) { /* pm_message("error in getting DataBlock size" ); */ return -1; } ZeroDataBlock = (count == 0)? TRUE :FALSE; if ((count != 0) && (! ReadOK(fd, buf, count))) { /* pm_message("error in reading DataBlock" ); */ return -1; } return (Int16)(count&0xFF); } Int16 GetCode(FILE *fd, Int16 code_size, Int16 flag) { static unsigned char buf[280]; static Int16 curbit, lastbit, done, last_byte; Int16 i, j, ret; unsigned char count; if (flag) { curbit = 0; lastbit = 0; done = FALSE; return 0; } if ( (curbit+code_size) >= lastbit) { if (done) { /*if (curbit >= lastbit)("ran off the end of my bits" );*/ return -1; } buf[0] = buf[last_byte-2]; buf[1] = buf[last_byte-1]; if ((count = (unsigned char)GetDataBlock(fd, buf+(2) )) == 0) done = TRUE; last_byte = (Int16)(2 + count); curbit = (Int16)((curbit - lastbit) + 16); lastbit = (Int16)((2+count)*8) ; } ret = 0; for (i = curbit, j = 0; j < code_size; ++i, ++j) ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; curbit += code_size; return ret; } Int16 LWZReadByte(FILE *fd, Int16 flag, Int16 input_code_size) { static Int16 fresh = FALSE; Int16 code, incode; register Int16 i; static Int16 code_size, set_code_size; static Int16 max_code, max_code_size; static Int16 firstcode, oldcode; static Int16 clear_code, end_code; static Int16 *sp; if (flag) { set_code_size = input_code_size; code_size = (Int16)(set_code_size+1); clear_code = (Int16)(1 << set_code_size) ; end_code = (Int16)(clear_code + 1); max_code_size = (Int16)(2*clear_code); max_code = (Int16)(clear_code+2); GetCode(fd, 0, TRUE); fresh = TRUE; for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } for (; i < (1< stack) return *--sp; while ((code = GetCode(fd, code_size, FALSE)) >= 0) { if (code == clear_code) { for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } for (; i < (1< 0); if (count != 0) { /* pm_message("missing EOD in data stream (common occurence)");*/ } return -2; } incode = code; if (code >= max_code) { *sp++ = firstcode; code = oldcode; } while (code >= clear_code) { *sp++ = table[1][code]; if (code == table[0][code]) { /*("circular table entry BIG ERROR");*/ return -1; } code = table[0][code]; } *sp++ = firstcode = table[1][code]; if ((code = max_code) <(1<= max_code_size) &&(max_code_size < (1< stack) return *--sp; } return code; } #endif /*NEWGIFD*/ #endif /*DeuTex*/ deutex-4.4.902/src/merge.c0000644000324500032450000004152310304422447014627 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include "tools.h" #include "endianm.h" #include "mkwad.h" #include "texture.h" #include "ident.h" #include "lists.h" #include "merge.h" #include /********** HDR fiddling with WAD ******************/ /* ** old references ** */ static const Int32 HDRdirSz=5*sizeof(struct WADDIR); static struct WADDIR HDRdir[6]; /* ** Take some entries from a WAD */ static void HDRplunderWad(struct WADINFO *rwad,struct WADINFO *ewad) { char *data; Int32 wsize,sz=0; Int32 ostart,osize; Int16 n; Int32 oldfilesz; /* ** calculate required size */ oldfilesz=WADRposition(rwad); /*old file size*/ /* ** copy entries from WAD */ Phase("ME10", "Copying entries from wad (please wait)"); data = (char *)Malloc(MEMORYCACHE); for(n=0;n<(rwad->ntry);n++) { /*if((n&0x7F)==0) Phase("."); FIXME need /dev/tty output */ ostart=rwad->dir[n].start; osize=rwad->dir[n].size; /*detect external entries */ if(ostart&EXTERNAL) { /*update new directory*/ WADRalign4(rwad); rwad->dir[n].start=WADRposition(rwad); /*get entry size*/ if(osize>0) { /*copy old entry */ WADRseek(ewad,ostart&(~EXTERNAL)); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE:osize-wsize; WADRreadBytes(ewad,data,sz); if(WADRwriteBytes2(rwad,data,sz)<0) { WADRchsize(rwad,oldfilesz); ProgError("ME13", "Not enough disk space"); break; } } } } } /*Phase("\n"); FIXME need /dev/tty output */ Free(data); } /* ** Copy a WAD, and link to it's entries */ static Int32 HDRinsertWad(struct WADINFO *rwad,struct WADINFO *ewad,Int32 *pesize) { char *data; Int32 wsize,sz=0; Int32 estart,esize; Int16 n; Int32 oldfilesz; /* ** calculate required size */ oldfilesz=WADRposition(rwad); /*old file size*/ WADRalign4(rwad); estart=WADRposition(rwad); WADRseek(ewad,0); esize=ewad->maxpos; Phase("ME16", "Inserting wad file into wad"); data = (char *)Malloc(MEMORYCACHE); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE:esize-wsize; WADRreadBytes(ewad,data,sz); if(WADRwriteBytes2(rwad,data,sz)<0) { WADRchsize(rwad,oldfilesz); ProgError("ME19", "Not enough disk space"); break; } /*if((wsize&0xF000)==0) Phase("."); FIXME need /dev/tty output */ } Free(data); for(n=0;n<(rwad->ntry);n++) { /*detect external entries */ if((rwad->dir[n].start)&EXTERNAL) { /*update new directory*/ rwad->dir[n].start &= (~EXTERNAL); rwad->dir[n].start += estart; } } /* Phase("\n"); FIXME need /dev/tty output */ *pesize= esize; return estart; } /*********** End fiddling with WAD ********************/ /******************* WAD restoration **********************/ void HDRrestoreWAD(const char *wadres) { struct WADINFO rwad; Int32 dirpos,ntry,n; Int32 rwadstart=0,rwadsize=0; Int32 ewadstart=0,ewadsize=0; static char ewadname[8]; static char ewadfile[40]; char *data; Int32 size=0,wsize=0,sz=0; Int32 time; FILE *fp; Bool Fail; Phase("ME22", "Attempting to restore wad %s", fname (wadres)); /*open DOOM.WAD*/ rwad.ok=0; WADRopenR(&rwad,wadres); /*get position of fake directory entry, reference to old dir*/ dirpos = rwad.dirpos - HDRdirSz; WADRseek(&rwad,dirpos); WADRreadBytes(&rwad,(char *)HDRdir,HDRdirSz); Fail=FALSE; if(peek_i32_le (&HDRdir[0].start) != 0x24061968L) Fail=TRUE; if(peek_i32_le (&HDRdir[0].size) != 666L) Fail=TRUE; if(strncmp(HDRdir[0].name,"IZNOGOOD",8)!=0) Fail=TRUE; if(Fail != FALSE) { if((n=WADRfindEntry(&rwad,"_DEUTEX_"))>=0) if(rwad.dir[n].size>=HDRdirSz) { dirpos=rwad.dir[n].start; WADRseek(&rwad,dirpos); WADRreadBytes(&rwad,(char *)HDRdir,HDRdirSz); Fail=FALSE; if(peek_i32_le (&HDRdir[0].start) != 0x24061968L) Fail=TRUE; if(peek_i32_le (&HDRdir[0].size) != 666L) Fail=TRUE; if(strncmp(HDRdir[0].name,"IZNOGOOD",8)!=0) Fail=TRUE; } } if(Fail != FALSE) ProgError("ME25", "Not a modified WAD"); Phase("ME28", "Restoration infos seem correct"); dirpos = peek_i32_le (&HDRdir[1].start); ntry = peek_i32_le (&HDRdir[1].size); rwadstart = peek_i32_le (&HDRdir[2].start); rwadsize = peek_i32_le (&HDRdir[2].size); ewadstart = peek_i32_le (&HDRdir[3].start); ewadsize = peek_i32_le (&HDRdir[3].size); Normalise(ewadname,HDRdir[3].name); /*name of WAD inside*/ /*original file time*/ time = peek_i32_le (&HDRdir[4].size); if(peek_i32_le (&HDRdir[4].start)!=FALSE) { /*extract the PWAD*/ sprintf(ewadfile,"%.8s.WAD",ewadname); #if DT_OS == 'd' #elif DT_OS == 'o' ToLowerCase(ewadfile); #else ToLowerCase(ewadfile); #endif fp=fopen(ewadfile,FOPEN_RB); if(fp!=NULL) { fclose(fp); Info("ME31", "%s already exists, internal WAD discarded", fname (ewadfile)); } else { Phase("ME34", "Restoring internal wad %s", fname (ewadfile)); if((fp=fopen(ewadfile,FOPEN_WB))!=NULL) { data = (char *)Malloc( MEMORYCACHE); size = ewadsize; WADRseek(&rwad,ewadstart); fseek(fp,0,SEEK_SET); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE : size-wsize; WADRreadBytes(&rwad,data,sz); errno = 0; if(fwrite(data,(size_t)sz,1,fp)!=1) { Warning("ME37", "%s: %s", fnameofs (ewadfile, (long) ewadstart), errno == 0 ? "write error" : strerror (errno)); break; } } Free(data); fclose(fp); } else Warning("ME40", "%s: %s", fname (ewadfile), strerror (errno)); } } WADRopenA(&rwad,wadres); /*correct the directory reference of DOOM.WAD*/ WADRsetDirRef(&rwad,ntry,dirpos); /*restore original size*/ WADRchsize(&rwad,rwadstart+rwadsize); WADRclose(&rwad); SetFileTime(wadres,time); Output("Restoration of %s should be successful\n", fname (wadres)); } /**************** End WAD restoration **********************/ static void HDRsetDir(struct WADINFO *rwad,Bool IsIwad,Bool Restore, Int32 time,Int32 dirpos,Int32 ntry,Int32 rsize, Int32 estart,Int32 esize,const char *wadext) { static char name[8]; Int32 pos; /*Set the old references */ Phase("ME43", "Writing new wad directory"); write_i32_le (&HDRdir[0].start, 0x24061968L); write_i32_le (&HDRdir[0].size, 666L); Normalise(HDRdir[0].name,"IZNOGOOD"); /*Set original WAD DIRECTORY*/ write_i32_le (&HDRdir[1].start, dirpos); write_i32_le (&HDRdir[1].size, ntry); Normalise(HDRdir[1].name,(IsIwad==TRUE)?"DOOM_DIR":"PWAD_DIR"); /*Store original WAD size and start*/ write_i32_le (&HDRdir[2].start, 0); write_i32_le (&HDRdir[2].size, rsize); Normalise(HDRdir[2].name,"ORIGINAL"); /*Store external WAD size and start*/ write_i32_le (&HDRdir[3].start, estart); write_i32_le (&HDRdir[3].size, esize); GetNameOfWAD(name,wadext); Normalise(HDRdir[3].name,name); /*old file time*/ write_i32_le (&HDRdir[4].size, time); write_i32_le (&HDRdir[4].start, Restore); Normalise(HDRdir[4].name,"TIME"); /*save position of old ref if no previous _DEUTEX_ */ WADRalign4(rwad); pos=(Int32)WADRfindEntry(rwad,"_DEUTEX_"); if(pos<0) { pos=WADRposition(rwad);/*BC++ 4.5 bug*/ WADRdirAddEntry(rwad,pos,HDRdirSz,"_DEUTEX_"); } /*write old refs*/ WADRwriteBytes(rwad,(char *)HDRdir,HDRdirSz); /*write the directory*/ rwad->dirpos = WADRposition(rwad); WADRwriteDir(rwad, 1); } /************ General services ******************/ /**************** Paste PWAD module ***********************/ /* ** merge WAD ** */ void PSTmergeWAD(const char *doomwad,const char *wadin,NTRYB select) { static struct WADINFO iwad; static struct WADINFO pwad; ENTRY *iiden; /*identify entry in IWAD*/ ENTRY *piden; /*identify entry in PWAD*/ Int16 pnm;char *Pnam;Int32 Pnamsz=0; Int32 dirpos,ntry,isize,pstart,psize,time; struct WADDIR *NewDir;Int32 NewNtry; Phase("ME46", "Attempting to merge iwad %s and pwad %s", fname (doomwad), wadin); /*open iwad,get iwad directory*/ iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES*/ pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) ProgError("ME49", "Can't find PNAMES in iwad"); Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz); /* identify iwad*/ iiden=IDENTentriesIWAD(&iwad, Pnam, Pnamsz,TRUE); /* get pwad directory, and identify*/ pwad.ok=0; WADRopenR(&pwad,wadin); piden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz); /**/ Free(Pnam); /*where to put pwad? at pwadstart*/ /* merge the two directories */ NewDir=LISmergeDir(&NewNtry,FALSE,TRUE,select,&iwad,iiden,0,&pwad,piden, EXTERNAL); /* prepare for append*/ time=WADRprepareAppend(doomwad,&iwad,NewDir,NewNtry,&dirpos,&ntry,&isize); /* complete IWAD with PWAD, restorable*/ pstart=HDRinsertWad(&iwad,&pwad,&psize); /* set directory */ HDRsetDir(&iwad,TRUE,TRUE,time,dirpos,ntry,isize,pstart,psize,wadin); /* close */ WADRclose(&pwad); WADRclose(&iwad); } /**************** End Paste PWAD module ****************/ /**************** Append IWAD after PWAD module *****************/ /* ** -app complete a PWAD with DOOM entries ** */ void ADDappendSpriteFloor(const char *doomwad, const char *wadres,NTRYB select) { struct WADINFO iwad; struct WADINFO pwad; ENTRY *iiden; /*identify entry in IWAD*/ ENTRY *piden; /*identify entry in PWAD*/ Int16 pnm;char *Pnam;Int32 Pnamsz; Int32 dirpos,ntry,psize,time; struct WADDIR *NewDir;Int32 NewNtry; Phase("ME52", "Appending sprites and/or flats"); Phase("ME52", " from iwad %s", fname (doomwad)); Phase("ME52", " to pwad %s", fname (wadres)); /* get iwad directory, and identify */ iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES*/ pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) ProgError("ME61", "Can't find PNAMES in iwad"); Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz); /* identify iwad*/ iiden=IDENTentriesIWAD(&iwad, Pnam, Pnamsz,TRUE); /* get pwad directory, and identify*/ pwad.ok=0; WADRopenR(&pwad,wadres); piden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz); /**/ Free(Pnam); /* merge the two directories */ NewDir=LISmergeDir(&NewNtry,TRUE,TRUE,select,&iwad,iiden,EXTERNAL,&pwad,piden,0); /* prepare for append*/ time=WADRprepareAppend(wadres,&pwad,NewDir,NewNtry,&dirpos,&ntry,&psize); /* append DOOM sprites to PWAD*/ HDRplunderWad(&pwad,&iwad); /* set dir */ HDRsetDir(&pwad,FALSE,FALSE,time,dirpos,ntry,psize,-1,-1,doomwad); /* close */ WADRclose(&iwad); WADRclose(&pwad); } /* ** join: complete a PWAD with another PWAD entries ** */ void ADDjoinWads(const char *doomwad, const char *wadres, const char *wadext,NTRYB select) { struct WADINFO iwad; /*IWAD*/ struct WADINFO ewad; /*external Wad*/ struct WADINFO rwad; ENTRY *eiden; /*identify entry in IWAD*/ ENTRY *riden; /*identify entry in PWAD*/ Int16 entry;char *Entry;Int32 EntrySz; Int16 pnm;char *Patch;Int32 PatchSz; Int32 start,size; Int16 etexu,rtexu; struct WADDIR *NewDir;Int32 NewNtry; Bool TexuMrg = FALSE; Int32 dirpos,ntry,rsize,estart,esize,time; Phase("ME64", "Merging pwad %s", fname (wadext)); Phase("ME64", " into pwad %s", fname (wadres)); /* get iwad directory, and identify */ iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES*/ entry=WADRfindEntry(&iwad,"PNAMES"); if(entry<0) ProgError("ME70", "Can't find PNAMES in iwad"); Entry=WADRreadEntry(&iwad,entry,&EntrySz); /* get ewad directory, and identify */ ewad.ok=0; WADRopenR(&ewad,wadext); eiden=IDENTentriesPWAD(&ewad, Entry, EntrySz); /* get rwad directory, and identify*/ rwad.ok=0; WADRopenR(&rwad,wadres); riden=IDENTentriesPWAD(&rwad, Entry, EntrySz); /**/ Free(Entry); /*merge texture1 if needed*/ etexu=WADRfindEntry(&ewad,"TEXTURE1"); rtexu=WADRfindEntry(&rwad,"TEXTURE1"); if((etexu>=0)&&(rtexu>=0)) { TexuMrg=TRUE; iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES in IWAD and init*/ pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) Bug("ME73", "JnPnm"); Entry=WADRreadEntry(&iwad,entry,&EntrySz); PNMinit(Entry,EntrySz); Free(Entry); /*declare TEXTURE1 from IWAD*/ TXUinit(); } WADRclose(&iwad); if(TexuMrg==TRUE) { /*add TEXTURE1 from rwad*/ Phase("ME76", " With TEXTURE1 from %s", fname (wadres)); PatchSz=0;Patch=NULL; pnm=WADRfindEntry(&rwad,"PNAMES"); if(pnm>=0) { Phase("ME79", " Declaring patches from %s", fname (wadres)); riden[pnm]=EVOID; Patch=WADRreadEntry(&rwad,pnm,&PatchSz); } Entry=WADRreadEntry(&rwad,rtexu,&EntrySz); TXUreadTEXTURE(rwad.dir[pnm].name, Entry, EntrySz, Patch, PatchSz, TRUE); if(PatchSz!=0)Free(Patch); Free(Entry); riden[rtexu]=EVOID; /* forget r texu*/ /*TEXTURE1 from ewad*/ Phase("ME82", " And TEXTURE1 from %s", fname (wadext)); PatchSz=0;Patch=NULL; pnm=WADRfindEntry(&ewad,"PNAMES"); if(pnm>=0) { Phase("ME85", " Declaring Patches from %s", fname (wadext)); eiden[pnm]=EVOID; Patch=WADRreadEntry(&ewad,pnm,&PatchSz); } Entry=WADRreadEntry(&ewad,etexu,&EntrySz); TXUreadTEXTURE(ewad.dir[pnm].name, Entry, EntrySz, Patch, PatchSz, FALSE); if(PatchSz!=0)Free(Patch); Free(Entry); eiden[etexu]=EVOID; /* forget e texu*/ } /* merge the two directories, all entries */ NewDir=LISmergeDir(&NewNtry,FALSE,FALSE,select,&rwad,riden,0,&ewad,eiden,EXTERNAL); /* prepare for append*/ time=WADRprepareAppend(wadres,&rwad,NewDir,NewNtry,&dirpos,&ntry,&rsize); /* append PWAD into PWAD, restorable */ estart=HDRinsertWad(&rwad,&ewad,&esize); /* append texu/pname*/ if(TexuMrg==TRUE) { WADRalign4(&rwad); start=WADRposition(&rwad); size=TXUwriteTEXTUREtoWAD(&rwad); WADRdirAddEntry(&rwad,start,size,"TEXTURE1"); TXUfree(); WADRalign4(&rwad); start=WADRposition(&rwad); size=PNMwritePNAMEtoWAD(&rwad); WADRdirAddEntry(&rwad,start,size,"PNAMES"); PNMfree(); } /* set directory */ HDRsetDir(&rwad,FALSE,TRUE,time,dirpos,ntry,rsize,estart,esize,wadext); /*end*/ WADRclose(&rwad); WADRclose(&ewad); } /* ** Add sprites and Floors ** ** must delete void entries (old DMADDS files) ** must select SPRITES of FLOORS ** */ /************** merge PWAD IWAD directory module ****************/ void ADDallSpriteFloor(const char *wadout, const char *doomwad, const char *wadres,NTRYB select) { struct WADINFO iwad; struct WADINFO pwad; struct WADINFO rwad; Int16 n; ENTRY *iiden; /*identify entry in IWAD*/ ENTRY *piden; /*identify entry in PWAD*/ Int32 start,size,ostart,osize; Int16 pnm;char *Pnam;Int32 Pnamsz; struct WADDIR *NewDir;Int32 NewNtry; Phase("ME88", "Copying sprites and/or flats"); Phase("ME88", " from iwad %s", fname (doomwad)); Phase("ME88", " and pwad %s", fname (wadres)); Phase("ME88", " into pwad %s", fname (wadout)); /* get iwad directory, and identify */ iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES*/ pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) ProgError("ME91", "Can't find PNAMES in main WAD"); Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz); /* identify iwad*/ iiden=IDENTentriesIWAD(&iwad, Pnam, Pnamsz,TRUE); /* get pwad directory, and identify*/ pwad.ok=0; WADRopenR(&pwad,wadres); piden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz); /**/ Free(Pnam); /*where to put pwad? at pwadstart*/ if((iwad.maxpos|pwad.maxpos)&EXTERNAL )Bug("ME94", "AddExt"); /* merge the two directories */ NewDir=LISmergeDir(&NewNtry,TRUE,TRUE,select,&iwad,iiden,EXTERNAL,&pwad,piden,0); /* create a new PWAD*/ rwad.ok=0; WADRopenW(&rwad,wadout,PWAD, 1); for(n=0;n /****OS/2****/ #elif DT_OS == 'o' # include # if DT_CC != 'b' # define filelength _filelength # endif /****UNIX****/ #else #endif #include #include #include #include #include "tools.h" #include "mkwad.h" #include "ident.h" #include "wadio.h" /*************Begin WAD module ********************** ** Open PWAD file. *pcount=global byte counter ** leaves number of entries and directory pointer NULL */ /******************End WAD module ******************/ const int WADR_READ=1; const int WADR_WRITE=2; const int WADR_RDWR=3; const int WADR_PIPO=8; /************ begin WAD module ***********/ void WADRopenPipo(struct WADINFO *info,Int32 ntry) { /*directory */ if((info->ok&WADR_RDWR)) Bug("WR80", "WadPpk"); info->ok=WADR_PIPO; if(ntry<=0) Bug("WR81", "WadPpo"); info->maxdir=ntry; info->dir=(struct WADDIR *)Malloc((info->maxdir)*sizeof(struct WADDIR)); info->maxpos=ntry*sizeof(struct WADDIR); info->ntry=0; info->wposit=info->maxpos; } struct WADDIR *WADRclosePipo(struct WADINFO *info,Int32 *ntry) { if((info->ok!=WADR_PIPO)) Bug("WR84", "WadPpc"); info->ok=FALSE; if(info->ntry<0)info->ntry=0; info->dir=(struct WADDIR *) Realloc(info->dir,(info->ntry)*sizeof(struct WADDIR)); *ntry=info->ntry; return info->dir; } Int32 WADRdirAddPipo(struct WADINFO *info,Int32 start,Int32 size, const char *entry) { Int16 n; if(info->ok!=WADR_PIPO) Bug("WR82", "WadDaP"); n=(Int16)info->ntry; /*position of new entry*/ if(n<0) Bug("WR83", "WadDa2"); if(nmaxdir) /*can add to the dir*/ { info->ntry++; /*new dir size*/ info->dir[n].size=size; info->dir[n].start=start; Normalise(info->dir[n].name,entry); } return n; /* nb entries */ } void WADRopenR(struct WADINFO *info, const char *wadin) { /*directory */ Int32 ntry,dirpos; Int16 n; struct WADDIR dir; if((info->ok&WADR_RDWR)) Bug("WR01", "%s: WadOpr", fname (wadin)); info->fd=fopen(wadin,FOPEN_RB); if((info->fd)==NULL) ProgError("WR03", "%s: %s", fname (wadin), strerror (errno)); info->filename = Malloc (strlen (wadin) + 1); strcpy (info->filename, wadin); info->ok=WADR_READ; /*signature*/ switch(WADRreadShort(info)) { case PWAD: case IWAD: break; default: ProgError("WR05", "%s: invalid wad magic", fname (wadin)); } if(WADRreadShort(info)!=WADMAGIC) ProgError("WR07", "%s: read error in header", fname (wadin)); /*start of directory*/ ntry = WADRreadLong(info); if(ntry<=0) ProgError("WR09", "%s: zero entries", fname (wadin)); if(ntry>=0x2000) ProgError("WR11", "%s: too many entries", fname (wadin)); info->dirpos= dirpos= WADRreadLong(info); if((dirpos<0)||(dirpos>0x10000000L)) ProgError("WR13", "%s: invalid directory offset %08lX", fname (wadin), (unsigned long) dirpos); /*allocate directory*/ info->maxdir=ntry; info->dir=(struct WADDIR *)Malloc((info->maxdir)*sizeof(struct WADDIR)); /*read directory, calculate further byte in wad*/ info->maxpos=dirpos+(ntry*sizeof(struct WADDIR)); WADRseek(info,dirpos); info->ntry=0; for(n=0;nfd, &dir.start) || wad_read_i32 (info->fd, &dir.size) || wad_read_name (info->fd, dir.name)) ProgError ("WR15", "%s: read error in directory", fname (wadin)); WADRdirAddEntry (info, dir.start, dir.size, dir.name); } if(info->ntry!=ntry) Bug("WR17", "WadOrN %ld %ld", (long) ntry, (long) info->ntry); info->wposit=info->maxpos; Phase("WR19", "Reading WAD %s:\t(%ld entries)", fname (wadin), (long) ntry); } static char signature[19 + 32]; void WADRopenW(struct WADINFO *info, const char *wadout,WADTYPE type, int verbose) { if (verbose) Phase("WW01", "Creating %s %s", (type==IWAD) ? "iwad" : "pwad", fname (wadout)); if((info->ok&WADR_RDWR)) Bug("WW02", "%s: WadOpW", fname (wadout)); /*check file*/ if(clobber==CLOBBER_NO) { info->fd = fopen(wadout, FOPEN_RB); if(info->fd!=NULL) ProgError("WW03", "Won't overwrite existing file %s", fname (wadout)); } /*open file*/ info->fd = fopen(wadout, FOPEN_WB); if(info->fd==NULL) ProgError("WW04", "%s: %s", fname (wadout), strerror (errno)); info->filename = Malloc (strlen (wadout) + 1); strcpy (info->filename, wadout); info->ok=WADR_WRITE; info->wposit=0; info->ntry =0; info->maxdir=MAXPWADDIR; info->dir =(struct WADDIR *)Malloc((info->maxdir)*sizeof(struct WADDIR)); WADRwriteShort(info,type); /* WAD type: PW or IW*/ WADRwriteShort(info,WADMAGIC); /* WAD type: AD*/ /* will be fixed when closing the WAD*/ WADRwriteLong(info,-1); /* no counter of dir entries */ WADRwriteLong(info,-1); /* no dir pointer */ /* DeuTex notice*/ sprintf(signature," DeuTex %.32s %cOJM 94 ",deutex_version,0xB8); /********----**----**-********/ WADRwriteBytes(info,signature,strlen(signature)); WADRalign4(info); } /* ** Assumes file already opened write ** if not, open it first ** OPEN READ-WRITE,not APPEND ** because APPEND can't FSEEK to start of file */ void WADRopenA(struct WADINFO *info, const char *wadinout) { Phase("WW10", "Modifying wad %s", fname (wadinout)); if((info->ok&WADR_WRITE)) Bug("WW11", "%s: WadOpA", fname (wadinout)); if(!(info->ok&WADR_READ)) { WADRopenR(info,wadinout); } /*reopen for append*/ fclose(info->fd); info->fd = fopen( wadinout, FOPEN_RBP); /*rb+ = read/write binary*/ if(info->fd==NULL) ProgError("WW12", "%s: %s", fname (wadinout), strerror (errno)); info->filename = Malloc (strlen (wadinout) + 1); strcpy (info->filename, wadinout); info->ok = WADR_RDWR; WADRseek(info,info->wposit); } /***************** Directory ***************/ /* ** Add a new entry in the directory ** increase ntry, redim dir ** update maxdir and maxpos ** returns entry ref */ Int32 WADRdirAddEntry(struct WADINFO *info,Int32 start,Int32 size, const char *entry) { Int16 n; Int32 sz; if(!(info->ok&(WADR_RDWR))) Bug("WW40", "%s: WadDAE", fname (info->filename)); n=(Int16)info->ntry; /*position of new entry*/ if(n>=info->maxdir) /*shall we move the dir?*/ { info->maxdir+=MAXPWADDIR; info->dir=(struct WADDIR *)Realloc((char *)info->dir,(info->maxdir)*sizeof(struct WADDIR)); } info->ntry++; /*new dir size*/ info->dir[n].size=size; info->dir[n].start=start; Normalise(info->dir[n].name,entry); sz=start+size; if(sz>info->maxpos) info->maxpos=sz; return n; /* nb entries */ } /* ** write the directory (names, counts, lengths) ** then update the number of entries and dir pointer */ void WADRwriteDir(struct WADINFO *info, int verbose) { Int16 n; if(!(info->ok&WADR_WRITE)) Bug("WW20", "%s: WadWD", fname (info->filename)); WADRalign4(info); /*align entry on Int32 word*/ info->dirpos=info->wposit; /*current position*/ /* write the new WAD directory*/ for(n=0;nntry;n++) { if (wad_write_i32 (info->fd, info->dir[n].start) || wad_write_i32 (info->fd, info->dir[n].size) || wad_write_name (info->fd, info->dir[n].name)) ProgError ("WW22", "%s: write error in directory", fname (info->filename)); } /* fix up the directory start information */ WADRsetDirRef(info,info->ntry,info->dirpos); n=(Int16)( info->dirpos+(sizeof(struct WADDIR)*info->ntry)); if(n>info->maxpos) info->maxpos=n; if (verbose) Phase("WW28", "%s: wad is complete, %ld entries, %ld bytes", fname (info->filename), (long) info->ntry, (long) info->wposit); } /***************** Wad structure *******************/ void WADRsetDirRef(struct WADINFO *info,Int32 ntry,Int32 dirpos) { #if 0 struct { Int32 ntry;Int32 dirpos;} Head; #endif if(!(info->ok&WADR_WRITE))Bug("WW24", "%s: WadSDR", fname (info->filename)); #if 0 Head.ntry=BE_Int32(ntry); Head.dirpos=BE_Int32(dirpos); #endif WADRseek(info,4); if (wad_write_i32 (info->fd, ntry) || wad_write_i32 (info->fd, dirpos)) ProgError ("WW26", "%s: write error while fixing up the header", fname (info->filename)); #if 0 if(fwrite(&Head,sizeof(Head),1,info->fd)!=1) { Warning("XX99", "That WAD might not be usable anymore!"); Warning("XX99", "Restore bytes 4 to 11 manually if you can."); ProgError("XX99", "Failed writing WAD directory References"); } #endif WADRseek(info,info->wposit); info->ntry=ntry; info->dirpos=dirpos; } void WADRchsize(struct WADINFO *info,Int32 fsize) { if(!(info->ok&WADR_WRITE)) Bug("WW93", "WadcSz"); if(Chsize(fileno(info->fd),fsize)!=0) ProgError("WW95", "%s: %s", fname (info->filename), strerror (errno)); /*@ AEO while trying the change the size of the wad */ info->maxpos=fsize; info->wposit=fsize; } #if 0 Bool WADRchsize2(struct WADINFO *info,Int32 fsize) { if(!(info->ok&WADR_WRITE)) Bug("XX99", "WadcSz"); if(Chsize(fileno(info->fd),fsize)!=0) return FALSE; return TRUE; } #endif /****************Read********************/ void WADRseek(struct WADINFO *info,Int32 position) { long ofs; if(!(info->ok&WADR_RDWR)) Bug("WR31", "WadSk"); ofs = ftell (info->fd); if(position>info->maxpos) Bug("WR33", "WadSk>"); if(fseek(info->fd,position,SEEK_SET)) ProgError("WR35", "%s: Can't seek to %06lXh (%s)", fnameofs (info->filename, ofs), (unsigned long) position, strerror (errno)); } /* * WADRreadBytes2 * Attempt to read up to bytes from wad . * Return the actual number of bytes read. */ iolen_t WADRreadBytes2 (struct WADINFO *info, char *buffer, iolen_t nbytes) { size_t attempt = MEMORYCACHE; iolen_t bytes_read = 0; if (!(info->ok&WADR_READ)) Bug("WR41", "WadRdB"); while (nbytes > 0) { size_t result; if (attempt > nbytes) attempt = nbytes; #if 0 { /* TEST */ const unsigned char *p; printf ("%p", info->fd); for (p = (const unsigned char *) info->fd; (FILE*) p < info->fd + 1; p += 4) printf (" %02X%02X%02X%02X", p[3], p[2], p[1], p[0]); putchar ('\n'); clearerr (info->fd); /* DEBUG */ } #endif result = fread (buffer, 1, attempt, info->fd); bytes_read += result; if (result == 0) /* Hit EOF */ break; buffer += result; nbytes -= result; } return bytes_read; } /* * WADRreadBytes * Attempt to read bytes from wad . If EOF * is hit too soon, trigger a fatal error. Else, return * . */ iolen_t WADRreadBytes (struct WADINFO *info, char *buffer, iolen_t nbytes) { long ofs = ftell (info->fd); iolen_t result = WADRreadBytes2 (info, buffer, nbytes); if (result != nbytes) if (ferror (info->fd)) ProgError ("WR43", "%s: read error (got %lu/%lu bytes)", fnameofs (info->filename, ofs), (unsigned long) result, (unsigned long) nbytes); else ProgError ("WR45", "%s: unexpected EOF (got %lu/%lu bytes)", fnameofs (info->filename, ofs), (unsigned long) result, (unsigned long) nbytes); return nbytes; } Int16 WADRreadShort(struct WADINFO *info) { Int16 res; long ofs = ftell (info->fd); if (!(info->ok&WADR_READ)) Bug("WR51", "WadRdS"); if (wad_read_i16 (info->fd, &res)) if (ferror (info->fd)) ProgError ("WR53", "%s: read error", fnameofs (info->filename, ofs)); else ProgError ("WR55", "%s: unexpected EOF", fnameofs (info->filename, ofs)); return res; } Int32 WADRreadLong(struct WADINFO *info) { Int32 res; long ofs = ftell (info->fd); if (!(info->ok&WADR_READ)) Bug("WR61", "WadRdL"); if (wad_read_i32 (info->fd, &res)) if (ferror (info->fd)) ProgError ("WR63", "%s: read error", fnameofs (info->filename, ofs)); else ProgError ("WR65", "%s: unexpected EOF", fnameofs (info->filename, ofs)); return res; } void WADRclose(struct WADINFO *info) { if(!(info->ok&WADR_RDWR)) Bug("WR97", "WadClo"); info->ok=FALSE; Free (info->filename); Free (info->dir); fclose (info->fd); } Int16 WADRfindEntry(struct WADINFO *info, const char *entry) { Int16 i; static char name[8]; struct WADDIR *dir; if(!(info->ok&WADR_RDWR)) Bug("WR91", "WadFE"); for(i=0,dir=info->dir;intry;i++,dir+=1) { Normalise(name,dir->name); if(strncmp(name,entry,8)==0) return i; } return -1; } /* ** load data in buffer */ char *WADRreadEntry(struct WADINFO *info,Int16 n,Int32 *psize) { char *buffer; Int32 start,size; if(!(info->ok&WADR_READ)) Bug("WR71", "WadRE"); if(n>=(info->ntry))Bug("WR73", "WadRE>"); start = info->dir[n].start; size = info->dir[n].size; buffer=(char *)Malloc(size); #if 0 fclose (info->fd); /* TEST */ info->fd = fopen(info->filename,"r+b"); /* TEST */ if (info->fd == NULL) /* TEST */ Warning("XX99", "Ugh!"); printf ("after %p\n", info->fd); #endif WADRseek(info,start); WADRreadBytes(info,buffer,size); *psize=size; return buffer; } /* * WADRreadEntry2 * Read at most the *psize first bytes of a lump. * If the lump is shorter than *psize, it's _not_ an error. * Return the actual number of bytes read in *psize. */ char *WADRreadEntry2 (struct WADINFO *info, Int16 n, Int32 *psize) { char *buffer; long start; iolen_t size; iolen_t actual_size; if (! (info->ok & WADR_READ)) Bug ("WR75", "WadRE"); if (n >= info->ntry) Bug ("WR76", "WadRE>"); start = info->dir[n].start; size = *psize < info->dir[n].size ? *psize : info->dir[n].size; buffer = Malloc (size); WADRseek (info, start); actual_size = WADRreadBytes2 (info, buffer, size); if (actual_size < size) if (ferror (info->fd)) ProgError ("WR78", "%s: Lump %s: read error at byte %ld", fnameofs (info->filename, start + actual_size), lump_name (info->dir[n].name), (long) actual_size); else ProgError ("WR79", "%s: Lump %s: unexpected EOF at byte %ld", fnameofs (info->filename, start + actual_size), lump_name (info->dir[n].name), (long) actual_size); *psize = actual_size; return buffer; } #if defined DeuTex /* ** copy data from WAD to file */ void WADRsaveEntry(struct WADINFO *info,Int16 n, const char *file) { Int32 wsize,sz=0; char *buffer; Int32 start,size; FILE *fd; if(!(info->ok&WADR_READ)) Bug("WR86", "WadSE"); if(n>=(info->ntry))Bug("WR87", "WadSE>"); start = info->dir[n].start; size = info->dir[n].size; fd=fopen(file,FOPEN_WB); if (fd==NULL) ProgError ("WR88", "%s: Can't open for writing (%s)", fname (file), strerror (errno)); buffer = (char *)Malloc( MEMORYCACHE); WADRseek(info,start); for(wsize=0; wsizeMEMORYCACHE)? MEMORYCACHE : size-wsize; WADRreadBytes(info,buffer,sz); if(fwrite(buffer,(size_t)sz,1,fd)!=1) { Free(buffer); ProgError ("WR89", "%s: write error", fname (file)); } } /*declare in WAD directory*/ Free( buffer); if (fclose(fd)) ProgError ("WR90", "%s: %s", fname (file), strerror (errno)); } #endif /*DeuTex*/ /******************** Write ************************/ void WADRsetLong(struct WADINFO *info,Int32 pos,Int32 val) { if(!(info->ok&WADR_WRITE)) Bug("WW56", "WadStL"); if(pos>(info->maxpos)) Bug("WW57", "WadSL>"); if(fseek(info->fd, pos, SEEK_SET)) ProgError ("WW58", "%s: Can't seek to %06lXh (%s)", fname (info->filename), (unsigned long) pos, strerror (errno)); if(wad_write_i32 (info->fd, val)) ProgError ("WW59", "%s: write error", fnameofs (info->filename, pos)); } void WADRsetShort(struct WADINFO *info,Int32 pos,Int16 val) { if(!(info->ok&WADR_WRITE)) Bug("WW51", "WadStS"); if(pos>(info->maxpos)) Bug("WW52", "WadSS>"); if(fseek(info->fd, pos, SEEK_SET)) ProgError ("WW53", "%s: Can't seek to %06lXh (%s)", fname (info->filename), (unsigned long) pos, strerror (errno)); if(wad_write_i16 (info->fd, val)) ProgError ("WW54", "%s: write error", fnameofs (info->filename, pos)); } /* ** internal functions ** */ static void WADRcheckWritePos(struct WADINFO *info) { if(!(info->ok&WADR_WRITE)) Bug("WW61", "WadCkW"); if (fseek( info->fd, info->wposit, SEEK_SET)) ProgError ("WW63", "%s: Can't seek to %06lXh (%s)", fnameofs (info->filename, ftell (info->fd)), info->wposit, strerror (errno)); } static Int32 WADRwriteBlock(struct WADINFO *info,char *data,Int32 sz) { if(fwrite(data,(size_t)sz,1,info->fd) != 1) ProgError("WW65", "%s: write error", fname (info->filename)); info->wposit += sz; if(info->maxposwposit)info->maxpos=info->wposit; return sz; } /* ** align, give position */ void WADRalign4(struct WADINFO *info) { Int16 remain; static char buffer[] ={0,0x24,0x6,0x68}; WADRcheckWritePos(info); remain = (Int16)(info->wposit&0x03); /*0 to 3*/ if(remain>0) WADRwriteBytes(info,buffer,4-remain); } /*must be equal to ftell*/ Int32 WADRposition(struct WADINFO *info) { WADRcheckWritePos(info); return info->wposit; } /* ** write */ Int32 WADRwriteLong(struct WADINFO *info,Int32 val) { WADRcheckWritePos(info); if (wad_write_i32 (info->fd, val)) ProgError ("WW67", "%s: write error", fname (info->filename)); info->wposit += sizeof val; if (info->maxpos < info->wposit) info->maxpos = info->wposit; return sizeof val; } Int32 WADRwriteShort(struct WADINFO *info,Int16 val) { WADRcheckWritePos(info); if (wad_write_i16 (info->fd, val)) ProgError ("WW69", "%s: write error", fname (info->filename)); info->wposit += sizeof val; if (info->maxpos < info->wposit) info->maxpos = info->wposit; return sizeof val; } Int32 WADRwriteBytes(struct WADINFO *info,char *data,Int32 size) { Int32 wsize,sz=0; WADRcheckWritePos(info); if(size<=0) Bug("WW71", "WadWb<"); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE : size-wsize; wsize+=WADRwriteBlock(info,&data[wsize],sz); } return wsize; } static Int32 WADRwriteBlock2(struct WADINFO *info,char *data,Int32 sz) { if(fwrite(data,(size_t)sz,1,info->fd) != 1)return -1; info->wposit += sz; if(info->maxposwposit)info->maxpos=info->wposit; return sz; } Int32 WADRwriteBytes2(struct WADINFO *info,char *data,Int32 size) { Int32 wsize,sz=0; WADRcheckWritePos(info); if(size<=0) Bug("WW73", "WadWb<"); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE : size-wsize; sz=WADRwriteBlock2(info,&data[wsize],sz); if(sz<0) return -1; wsize+=sz; } return wsize; } /* ** copy data from SOURCE WAD to WAD */ Int32 WADRwriteWADbytes(struct WADINFO *info,struct WADINFO *src,Int32 start,Int32 size) { Int32 wsize,sz=0; char *data; data = (char *)Malloc( MEMORYCACHE); WADRseek(src,start); WADRcheckWritePos(info); for(wsize=0; wsizeMEMORYCACHE)? MEMORYCACHE : size-wsize; WADRreadBytes(src,data,sz); wsize+=WADRwriteBlock(info,data,sz); } /*declare in WAD directory*/ Free( data); return wsize; } #if defined DeuTex /* ** copy lump from file into WAD ** returns size */ Int32 WADRwriteLump(struct WADINFO *info, const char *file) { Int32 size,sz=0; FILE *fd; char *data; WADRcheckWritePos(info); /*Look for entry in master directory */ fd=fopen(file,FOPEN_RB); if (fd==NULL) ProgError("WW75", "%s: %s", fname (file), strerror (errno)); data = (char *)Malloc( MEMORYCACHE); for(size=0;;) { sz = fread(data,1,(size_t)MEMORYCACHE,fd); if(sz<=0)break; size+=WADRwriteBlock(info,data,sz); } Free( data); fclose(fd); return size; } Int32 WADRwriteWADentry(struct WADINFO *info,struct WADINFO *src,Int16 n) { if(n>(src->ntry)) Bug("WW77", "WadWW>"); return WADRwriteWADbytes(info,src,src->dir[n].start,src->dir[n].size); } /* ** copy level parts */ void WADRwriteWADlevelParts(struct WADINFO *info,struct WADINFO *src,Int16 N, size_t nlumps) { Int32 start,size; Int16 n; for (n = N + 1; n < src->ntry && n < N + nlumps; n++) { WADRalign4 (info); start = WADRposition (info); size = WADRwriteWADentry (info, src, n); WADRdirAddEntry (info, start, size, src->dir[n].name); } } /* ** copy level from WAD ** try to match level name (multi-level) ** if level name not found, then take the first level... */ void WADRwriteWADlevel(struct WADINFO *info, const char *file, const char *level) { Int16 N,l; Int32 pos; /*char Level[8];*/ struct WADINFO src; if(IDENTlevel(level)<0)ProgError("WW79", "Bad level name %s",level); src.ok=0; WADRopenR(&src,file); /*search for entry in level*/ N=WADRfindEntry(&src,level); if(N<0) /* no? then search first level*/ { for(N=0;;N++) { l=IDENTlevel(src.dir[N].name); if(l>=0)break; if(N>=src.ntry) ProgError("WW81", "No level in WAD %s",file); } } /*set level name*/ WADRalign4(info); pos=WADRposition(info); /*BC++ 4.5 bug!*/ WADRdirAddEntry(info,pos,0L,level); /* 9999 is a way of saying "copy all the lumps". The rationale is "let's assume the user knows what he/she is doing. If he/she wants us to include a 100-lump level, let's do it". On the other hand, this stance is in contradiction with using WADRfindEntry() (see above). This needs to be fixed. There are two choices : - make this function discriminating and prevent experimentation - make it dumb but allow one to put multi-level wads in levels/. My real motivation for doing things the way I did was that I didn't want to copy-paste from IDENTdirLevels() into WADRwriteWADlevelParts() (these things should be at a single place). */ WADRwriteWADlevelParts(info,&src,N, 9999); WADRclose(&src); } #endif /*DeuTex*/ /* ** replace dir of rwad by dir of newwad ** prepare to write at the end of rwad ** open for append */ Int32 WADRprepareAppend(const char *wadres,struct WADINFO *rwad, struct WADDIR *NewDir,Int32 NewNtry, Int32 *dirpos,Int32 *ntry, Int32 *size) { Int32 ewadstart; Int32 rwadsize; Int32 time; time=GetFileTime(wadres); /* append to the Result WAD*/ WADRopenA(rwad,wadres); /*get original size*/ #if DT_OS == 'd' # if DT_CC == 'd' rwadsize=rwad->maxpos; # else rwadsize=filelength(fileno(rwad->fd)); # endif #elif DT_OS == 'o' rwadsize=filelength(fileno(rwad->fd)); #else rwadsize=rwad->maxpos; #endif /*last warning*/ Output("The WAD file %s will be modified, but it can be restored with:\n",wadres); Output("%s -res %s\n",COMMANDNAME,wadres); Output("Restoration may fail if you modified the WAD with another tool.\n"); Output("In case of failure, you can salvage your WAD by:\n"); /* Assuming wad is little endian... */ Output("- setting bytes 4-7 to \t%02Xh %02Xh %02Xh %02Xh\n", (unsigned short) (rwad->ntry & 0xff), (unsigned short) ((rwad->ntry >> 8) & 0xff), (unsigned short) ((rwad->ntry >> 16) & 0xff), (unsigned short) ((rwad->ntry >> 24) & 0xff)); Output("- and setting bytes 8-11 to \t%02Xh %02Xh %02Xh %02Xh\n", (unsigned short) (rwad->dirpos & 0xff), (unsigned short) ((rwad->dirpos >> 8) & 0xff), (unsigned short) ((rwad->dirpos >> 16) & 0xff), (unsigned short) ((rwad->dirpos >> 24) & 0xff)); Output("If possible, set the file size to %ld bytes.\n",rwadsize); /*align*/ ewadstart=((rwadsize+0xF)&(~0xFL)); if((ewadstart|rwadsize)&EXTERNAL) ProgError("WW91", "Too big WADs"); *dirpos=rwad->dirpos; *ntry=rwad->ntry; *size=rwadsize; /*Change size*/ WADRchsize(rwad,ewadstart); /*Write will start at file end*/ rwad->maxpos=ewadstart; rwad->wposit=ewadstart; WADRseek(rwad,ewadstart); /*Change to New directory*/ Free(rwad->dir); rwad->dir=NewDir; rwad->ntry=NewNtry; rwad->maxdir=NewNtry; rwad->dirpos = -1; return time; } deutex-4.4.902/src/picture.c0000644000324500032450000013071510305327733015210 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include #include "tools.h" #include "endianio.h" #include "endianm.h" #include "mkwad.h" #include "picture.h" #include "ident.h" #include "color.h" #include "usedidx.h" #ifdef DeuTex static int wall_to_raw (char *data, Int32 datasz, const char *name); #endif /* * parse_pic_header * * buf Data for the entire lump containing the * hypothethical image. * bufsz Size of buf in bytes. * h Pointer on struct through which * parse_pic_header() returns the characteristic * of the picture header. * message Pointer on char[81]. If an error occurs (non-zero * return value) and is not NULL, a * string of at most 80 characters is written * there. * * Return 0 on success, non-zero on failure. */ #define FAIL0(s) do{if (message) strcpy (message, s); return 1;}while(0) #define FAIL1(f,a) do{if (message) sprintf (message, f, a); return 1;}while(0) int parse_pic_header ( const char *buf, long bufsz, pic_head_t *h, char *message) { /* Current byte of pic buffer */ const unsigned char *p = (const unsigned char *) buf; /* Last byte of pic buffer */ const unsigned char *buf_end = ((const unsigned char *) buf) + bufsz - 1; /* Details of picture format in wad */ h->dummy_bytes = picture_format == PF_NORMAL; h->colofs_size = (picture_format == PF_NORMAL) ? 4 : 2; /* Read the picture header */ if (picture_format == PF_ALPHA) { if (p + 4 - 1 > buf_end) FAIL0 ("header too short"); h->width = *p++; h->height = *p++; h->xofs = *p++; h->yofs = *p++; } else if (picture_format == PF_ROTT) { Int16 unknown; if (p + 10 - 1 > buf_end) FAIL0 ("header too short"); read_i16_le (p, &unknown); /* FIXME find out what it's for */ p += 2; read_i16_le (p, &h->width); p += 2; read_i16_le (p, &h->height); p += 2; read_i16_le (p, &h->xofs); p += 2; read_i16_le (p, &h->yofs); p += 2; } else { if (p + 8 - 1 > buf_end) FAIL0 ("header too short"); read_i16_le (p, &h->width); p += 2; read_i16_le (p, &h->height); p += 2; read_i16_le (p, &h->xofs); p += 2; read_i16_le (p, &h->yofs); p += 2; } /* Sanity checks on picture size and offsets */ if (h->width < 1) FAIL1 ("width < 1 (%d)", (int) h->width); if (h->height < 1) FAIL1 ("height < 1 (%d)", (int) h->height); #if 0 /*if (h->width > 4096) FAIL1 ("width > 4096 (%d)", (int) h->width);*/ if (h->height > 4096) FAIL1 ("height > 4096 (%d)", (int)h->height); if (h->xofs < -4096) FAIL1 ("X-offset < -4096 (%d)", (int) h->xofs); if (h->xofs > 4096) FAIL1 ("X-offset > 4096 (%d)", (int) h->xofs); if (h->yofs < -4096) FAIL1 ("Y-offset < -4096 (%d)", (int) h->yofs); if (h->yofs > 4096) FAIL1 ("Y-offset > 4096 (%d)", (int) h->yofs); #endif /* Array of column offsets. Column data. */ h->colofs = p; p += (long) h->colofs_size * h->width; if (p > buf_end) FAIL0 ("offsets table too short"); h->data = p; return 0; /* Success */ } /*compile only for DeuTex*/ #if defined DeuTex /* BMP,GIF,DoomPIC conversion ** intermediary format: RAW (FLAT= RAW 64x64 or RAW 64x65) ** Int16 Xsz Int16 Ysz ** char idx[Xsz*Ysz] ** colors= those of DOOM palette ** position (x,y) = idx[x+xsz*y] ** insertion point not set */ /* ** */ static char *PICtoRAW (Int16 *prawX, Int16 *prawY, Int16 *pXinsr, Int16 *pYinsr, const char *pic,Int32 picsz, char transparent, const char *name, cusage_t *cusage); static char *RAWtoPIC (Int32 *ppicsz, char *raw, Int16 rawX, Int16 rawY, Int16 Xinsr, Int16 Yinsr, char transparent); static char *snea_to_raw (Int16 *prawX, Int16 *prawY, Int16 *pXinsr, Int16 *pYinsr, const char *snea, Int32 sneasz, const char *name, cusage_t *cusage); static void RAWtoBMP (char *file, char *raw, Int16 rawX, Int16 rawY, struct PIXEL *doompal); static char *BMPtoRAW(Int16 *prawX, Int16 *prawY, char *file); static void RAWtoPPM (char *file, char *raw, Int16 rawX, Int16 rawY, struct PIXEL *doompal); static char *PPMtoRAW (Int16 *prawX, Int16 *prawY, char *file); static char *GIFtoRAW (Int16 *rawX, Int16 *rawY, char *file); static void RAWtoGIF (char *file, char *raw, Int16 rawX, Int16 rawY, struct PIXEL *doompal); /* ** ** this is only a test example ** COLinit and COLfree must be called before ** BMP->GIF */ #if 0 void PicDebug(char *file, const char *bmpdir, const char *name) { char *raw; Int16 rawX,rawY; struct PIXEL * doompal; Phase("XX99", "BMP->RAW"); MakeFileName(file,bmpdir,"","",name,"BMP"); raw =BMPtoRAW(&rawX,&rawY,file); doompal = COLdoomPalet(); Phase("XX99", "RAW->GIF"); MakeFileName(file,bmpdir,"","",name,"GIF"); RAWtoGIF(file,raw,rawX,rawY,doompal); Free(raw); } #endif /* ** this is only a test example ** GIF->BMP */ #if 1 void PicDebug(char *file,const char *bmpdir, const char *name) { char *raw; Int16 rawX=0,rawY=0; struct PIXEL * doompal; Phase("DB10", "GIF->RAW"); MakeFileName(file,bmpdir,"","",name,"GIF"); raw =GIFtoRAW(&rawX,&rawY,file); doompal = COLdoomPalet(); Phase("DB20", "RAW->BMP"); MakeFileName(file,bmpdir,"","",name,"BMP"); RAWtoBMP(file,raw,rawX,rawY,doompal); Free(raw); } #endif /* ** end of examples ** */ /* ** BMP, GIF or PPM ** */ Bool PICsaveInFile (char *file, PICTYPE type, char *pic, Int32 picsz, Int16 *pXinsr, Int16 *pYinsr, IMGTYPE Picture, const char *name, cusage_t *cusage) { char *raw=NULL; Int16 rawX = 0; /* Initialise to placate GCC */ Int16 rawY = 0; /* Initialise to placate GCC */ struct PIXEL *doompal; char transparent; /*Warning ("XX99", "PICsaveInFile: %s", fname (file));*/ transparent =(char)COLinvisible(); *pXinsr=INVALIDINT; /*default insertion point X*/ *pYinsr=INVALIDINT; /*default insertion point Y*/ switch(type) { case PGRAPH: case PWEAPN: case PSPRIT: case PPATCH: /*Warning ("XX99", "PICtoRAW: %s", fname (file));*/ raw = PICtoRAW (&rawX, &rawY, pXinsr, pYinsr, pic, picsz, transparent, name, cusage); if (raw==NULL) return FALSE; /*was not a valid DoomPic*/ break; case PFLAT: if(picsz==0x1000L) { rawX=64;rawY=64;} else if(picsz==0x1040) { rawX=64;rawY=65;} /* Heretic scrolling flat */ else if(picsz==0x2000) { rawX=64;rawY=128;} /* Hexen scrolling flat */ else return FALSE;/*Wrong size for FLAT. F_SKY1*/ raw=pic; /*flat IS raw already*/ if (cusage != NULL) usedidx_rectangle (pic, picsz, name, cusage); break; case PWALL: if(picsz==4096) { rawX=64;rawY=64;} else return FALSE;/*Wrong size for WALL.*/ if (wall_to_raw (pic, picsz, name) != 0) ProgError ("GW88", "Wall %s: wall_to_raw error", lump_name (name)); raw = pic; if (cusage != NULL) usedidx_rectangle (pic, picsz, name, cusage); break; case PSNEAP: case PSNEAT: raw = snea_to_raw (&rawX, &rawY, pXinsr, pYinsr, pic, picsz, name, cusage); if (raw == NULL) return FALSE; break; case PLUMP: /* Heretic, Hexen and Strife store some large bitmaps this way. */ if(picsz==64000L) { rawX=320; rawY=200; } else return FALSE;/*Wrong size for LUMP. F_SKY1*/ raw=pic; /*flat IS raw already*/ if (cusage != NULL) usedidx_rectangle (pic, picsz, name, cusage); break; default: Bug("GW90", "Invalid type %d", (int) type); } if (cusage == NULL) { /* ** load game palette (PLAYPAL or TITLEPAL) */ if (type == PSNEAT) doompal = COLaltPalet(); else doompal = COLdoomPalet(); /* ** convert to BMP/GIF/PPM */ switch(Picture) { case PICGIF: RAWtoGIF(file,raw,rawX,rawY,doompal); break; case PICBMP: RAWtoBMP(file,raw,rawX,rawY,doompal); break; case PICPPM: RAWtoPPM(file,raw,rawX,rawY,doompal); break; default: Bug("GW91", "Invalid picture format %d", (int) Picture); } } switch(type) { case PGRAPH: case PWEAPN: case PSPRIT: case PPATCH: case PSNEAP: case PSNEAT: Free(raw); break; case PFLAT: /*don't free pic!*/ case PLUMP: case PWALL: break; } return TRUE; } Int32 PICsaveInWAD(struct WADINFO *info,char *file,PICTYPE type,Int16 Xinsr,Int16 Yinsr,IMGTYPE Picture) { char *raw=NULL; Int16 rawX=0,rawY=0; char *pic=NULL; Int32 picsz = 0; /* Initialise to placate GCC */ char transparent; /* ** convert BMP to RAW */ transparent =COLinvisible(); switch(Picture) { case PICGIF: raw = GIFtoRAW(&rawX,&rawY,file); break; case PICBMP: raw = BMPtoRAW(&rawX,&rawY,file); break; case PICPPM: raw = PPMtoRAW(&rawX,&rawY,file); break; default: Bug("GB02", "Invalid picture conversion %d", (int)Picture); } if (rawX < 1) ProgError ("GB10", "%s: picture width < 1", fname (file)); if (rawY < 1) ProgError ("GB11", "%s: picture height < 1", fname (file)); /* AYM (256 -> 509) */ if(rawY>509) ProgError ("GB13", "%s: picture height > 509", fname (file)); switch(type) { case PGRAPH: case PWEAPN: case PSPRIT: case PPATCH: break; case PFLAT: /*flats*/ if(rawX!=64) Warning ("FB10", "%s: weird width for a flat (not 64)", fname (file)); if(rawY!=64 && rawY!=65 && rawY != 128) Warning ("FB11", "%s: weird height for a flat (not 64, 65 or 128)", fname (file)); break; case PLUMP: /*special heretic lumps*/ if(rawX!=320) Warning ("LB10", "%s: weird width for a lump (not 320)", fname (file)); if(rawY!=200) Warning ("LB11", "%s: weird height for a lump (not 200)", fname (file)); break; case PWALL: if(rawX!=64) Warning("WB10", "%s: weird width for a wall (not 64)", fname (file)); if(rawY!=64) Warning("WB11", "%s: weird height for a wall (not 64)", fname (file)); break; default: Bug("GB91", "Invalid type %d", (int)type); } /* ** calculate insertion point */ Xinsr=IDENTinsrX(type,Xinsr,rawX); Yinsr=IDENTinsrY(type,Yinsr,rawY); /* ** convert RAW to DoomPic */ switch(type) { case PGRAPH: case PWEAPN: case PSPRIT: case PPATCH: pic=RAWtoPIC(&picsz,raw,rawX,rawY,Xinsr,Yinsr,transparent); Free(raw); WADRwriteBytes(info,pic,picsz); Free(pic); break; case PLUMP: /*LUMP is RAW*/ case PFLAT: /*FLAT is RAW*/ picsz= ((Int32)rawX)*((Int32)rawY); WADRwriteBytes(info,raw,picsz); Free(raw); break; case PWALL: /* FIXME rotate 270° */ picsz= ((Int32)rawX)*((Int32)rawY); WADRwriteBytes(info,raw,picsz); Free(raw); break; } /* ** write DoomPic in WAD */ return picsz; } /******************* DoomPic module ************************/ /* ** doom pic ** */ struct PICHEAD { Int16 Xsz; /*nb of columns*/ Int16 Ysz; /*nb of rows*/ Int16 Xinsr; /*insertion point*/ Int16 Yinsr; /*insertion point*/ }; /* ** RAW to DoomPIC conversion ** ** in: Int16 Xinsr; Int16 Yinsr; ** Int16 rawX; Int16 rawY; char transparent; ** char raw[Xsize*Ysize] ** out: Int32 picsz; size of DoomPIC ** char pic[picsz]; buffer for DoomPIC */ #if DT_OS == 'd' #define OPTIMEM 1 /*DOS: alloc < 64k if possible*/ #else #define OPTIMEM 0 #endif static char *RAWtoPIC(Int32 *ppicsz, char *raw, Int16 rawX, Int16 rawY, Int16 Xinsr,Int16 Yinsr, char transparent) { Int16 x,y; char pix,lastpix; /*pixels*/ /*Doom PIC */ char *pic; /*picture*/ Int32 picsz,rawpos; struct PICHEAD *pichead; /*header*/ Int32 *ColOfs; /*position of column*/ /*columns composed of sets */ char *Set=NULL; Int32 colnbase,colnpos,setpos; Int16 setcount=0; /*offset of first column*/ colnbase= sizeof(struct PICHEAD)+((Int32)rawX)*sizeof(Int32); /* worst expansion when converting from PIXEL column to ** list of sets: (5*Ysize/2)+1, corresponding to a dotted vertical ** transparent line. Ysize/2 dots, 4overhead+1pix, 1 last FF code. ** but if too big, allow only a 10 split mean per line */ /*this memory optimisation doesn't work for big pics with many transparent areas. it limits the number of transp slots to a mean of 10. so a resize could be needed later. else, the biggest would be 162k */ /* AYM 1999-05-09: changed the calculation of picsz. Previously, it was assumed that the worst case was when every second pixel was transparent. This is not true for textures that are only 2-pixel high; in that case, if the two pixels are opaque, the column uses 7 bytes. The old code thought that was 6 bytes, and overflowed the buffer for at least one picture (Strife's STBFN045). */ /* Highest possible picture : Post 1 yofs = 0 length = 254 Post 2 yofs = 254 length = 255 Max height is 509 pixels. */ { /* FIXME */ int worst_case_1 = 5 * (((long) rawY + 1) / 2) + 1 + 1; /* "+ 1" matters ! */ int worst_case_2 = 4 + rawY + 1; int worst_case = worst_case_1 > worst_case_2 ? worst_case_1 : worst_case_2; picsz= colnbase + ((Int32)rawX) * worst_case; } #if OPTIMEM /*optimisation*/ if(picsz>0x10000L) picsz=0x10000L; #endif pic = (char *)Malloc(picsz); ColOfs=(Int32 *)&(pic[sizeof(struct PICHEAD)]); pichead=(struct PICHEAD *)pic; /* ** convert raw (doom colors) to PIC */ write_i16_le (&pichead->Xsz, rawX); write_i16_le (&pichead->Ysz, rawY); write_i16_le (&pichead->Xinsr, Xinsr); write_i16_le (&pichead->Yinsr, Yinsr); colnpos=colnbase; for(x=0;x= 509) { Warning("PI20", "Column has more than 509 pixels, truncating at (%d,%d)", (int) x, (int) y); break; } if(lastpix==transparent) /* begining of post */ { Set=(char *)&(pic[colnpos+setpos]); setcount=0; Set[0]=y; /* y position */ Set[1]=0; /*count (updated later)*/ Set[2]=pix; /*unused*/ } Set[3+setcount]=pix;/*non transparent pixel*/ setcount++; /*update count of pixel in set*/ } else /*pix is transparent*/ { if(lastpix!=transparent)/*finish the current set*/ { Set[1]=setcount; Set[3+setcount]=lastpix; setpos+= 3+setcount+1;/*1pos,1cnt,1dmy,setcount pixels,1dmy*/ } /*else: not in set but in transparent area*/ } lastpix=pix; } if(lastpix!=transparent) /*finish current set, if any*/ { Set[1]=setcount; Set[3+setcount]=lastpix; setpos+= 3+setcount+1; /*1pos,1count,1dummy,setcount pixels,1dummy*/ } pic[colnpos+setpos]=(char)0xFF; /*end of all sets*/ colnpos+=(Int32)(setpos+1); /*position of next column*/ #if OPTIMEM /*optimisation*/ if((colnpos+((Int32)(5*rawY)/2)+1)>=picsz) /*avoid crash during next column*/ { /*pic size was underestimated. need more pic size*/ /*Bug("Pic size too small");*/ #if 1 picsz= colnpos+0x4000;/*better make it incremental... not 161k!*/ #else picsz= colnbase + ((Int32)rawX) * (1+5*(((Int32)rawY+1)/2)); #endif pic = (char *)Realloc(pic,picsz); ColOfs=(Int32 *)&(pic[sizeof(struct PICHEAD)]); } #endif } /*picsz was an overestimated size for PIC*/ pic = (char *)Realloc(pic,colnpos); *ppicsz= colnpos;/*real size of PIC*/; return pic; } /* ** DoomPIC to RAW ** ** in: Int32 picsz; transparent; ** char pic[picsz]; ** out: Int16 rawX; Int16 rawY; ** char raw[rawX*rawY]; ** NULL if it's not a valid pic ** ** The parameter is normally NULL. If -usedidx is given, ** it points to an object of type cusage_t. ** That block is for colour usage statistics and we update it. */ static char *PICtoRAW(Int16 *prawX,Int16 *prawY,Int16 *pXinsr,Int16 *pYinsr, const char *pic,Int32 picsz,char transparent, const char *name, cusage_t *cusage) { Int16 x,y; /*pixels*/ const void *offsets; /* Last byte of pic buffer */ const unsigned char *pic_end = ((const unsigned char *) pic) + picsz - 1; /*raw picture*/ char col,notransp; char *raw; Int32 rawpos,rawsz; pic_head_t h; int nw = 5; /* Number of warnings left */ if (cusage != NULL) usedidx_begin_lump (cusage, name); notransp=0;/* this is to avoid trouble when the transparent index is used in a picture */ /* Read the header of the picture */ { char message_buf[81]; if (parse_pic_header (pic, picsz, &h, message_buf)) { Warning ("PI10", "Picture %s: %s, skipping picture", lump_name (name), message_buf); return NULL; } } offsets = h.colofs; /* Read all columns, post by post */ /* allocate raw. (care: free it if error, before exit) */ /*Warning ("XX99", "%s: %d x %d", lump_name (name), (int) h.width, (int) h.height);*/ rawsz = (long) h.width * h.height; raw = (char *) Malloc (rawsz); Memset (raw, transparent, rawsz); for (x = 0; x < h.width; x++) { const unsigned char *post = NULL; /* Initialised to avoid a warning */ if (h.colofs_size == 4) { Int32 ofs; read_i32_le (((const Int32 *) offsets) + x, &ofs); post = (const unsigned char *) (pic + ofs); } else if (h.colofs_size == 2) { /* In principle, the offset is signed. However, considering it unsigned helps extracting patches larger than 32 kB, like W18_1 (alpha) or SKY* (PR). Interestingly, Doom alpha and Doom PR treat the offset as signed, which is why some textures appear with tutti-frutti on the right. -- AYM 1999-09-18 */ UInt16 ofs; read_i16_le (((const Int16 *) offsets) + x, (Int16 *) &ofs); post = (const unsigned char *) (pic + ofs); } else { Bug ("PI90", "Invalid colofs_size %d", (int) h.colofs_size); /* Can't happen */ } /*Warning ("XX99", "%s: %03d %p %p %p", lump_name (name), x, pic, post, pic_end );*/ if (post < (const unsigned char *) pic) { LimitedWarn (&nw, "PI11", "Picture %s(%d): column has bad offset %ld, skipping column", lump_name (name), (int) x, (long) ((const char *) pic - (const char *) post)); continue; } if (post < h.data) { LimitedWarn (&nw, "PI12", "Picture %s(%d): column has suspicious offset %ld", lump_name (name), (int) x, (long) ((const char *) pic - (const char *) post)); } /* Read an entire post */ for (;;) { int post_length; const unsigned char *post_end; if (post > pic_end) { LimitedWarn (&nw, "PI13", "Picture %s(%d): post starts past EOL, skipping rest of column", lump_name (name), (int) x); goto done_with_column; } /* Read the header of the post */ if (*post == 0xff) break; /* Last post */ y = *post++; post_length = *post++; if (h.dummy_bytes) post++; post_end = post + post_length; if (post_end > pic_end) { LimitedWarn (&nw, "PI14", "Picture %s(%d): post spans EOL, skipping rest of column", lump_name (name), (int) x); goto done_with_column; /* Used to be fatal--AYM 1999-10-16 */ } /* Read the middle of the post */ for (;post < post_end; y++) { if (y >= h.height) { LimitedWarn (&nw, "PI15", "Picture %s(%d): post Y-offset too high, skipping rest of column", lump_name (name), (int) x); goto done_with_column; /* Used to be fatal--AYM 1999-10-16 */ } col = *post++; if (cusage != NULL) usedidx_pixel (cusage, (unsigned char) col); if(col==transparent){col=notransp;} rawpos = x + (long) h.width * y; raw[rawpos]=col; } /* Read the trailer of the post */ if (h.dummy_bytes) post++; } done_with_column: ; } /*return*/ LimitedEpilog (&nw, "PI16", "Picture %s: ", lump_name (name)); if (cusage != NULL) usedidx_end_lump (cusage); *pXinsr = h.xofs; *pYinsr = h.yofs; *prawX = h.width; *prawY = h.height; return raw; } /******************* End DoomPic module ************************/ /******************* Snea module ************************/ static char *snea_to_raw (Int16 *prawX, Int16 *prawY, Int16 *pXinsr, Int16 *pYinsr, const char *sneabuf, Int32 sneasz, const char *name, cusage_t *cusage) { const unsigned char *snea = (const unsigned char *) sneabuf; int width = snea[0] * 4; int height = snea[1]; unsigned long pixels = (long) width * height; unsigned char *raw = Malloc (pixels); const unsigned char *s = snea + 2; const unsigned char *end_of_snea = snea + sneasz; unsigned char *r = raw; unsigned char *end_of_raw = raw + pixels; if (pixels + 2 != sneasz) { Warning ("SN10", "Snea %s: mismatch between size and geometry, skipping snea", lump_name (name)); Free (raw); return NULL; } while (s < end_of_snea) { *r = *s++; r += 4; if (r >= end_of_raw) r -= pixels - 1; } if (cusage != NULL) usedidx_rectangle (raw, pixels, name, cusage); *prawX = width; *prawY = height; return raw; } /******************* End snea module ************************/ /******************* ROTT wall module ************************/ /* * wall_to_raw - convert ROTT wall data to a RAW bitmap * * A ROTT wall is a 64x64 pixel matrix, read down and right. To * convert it to RAW format, mirror it along the first diagonal * ((0,0)-(63,63)). */ #define WALL_DIM 64 static int wall_to_raw (char *data, Int32 datasz, const char *name) { char *s = data + 1; char *d = s + WALL_DIM - 1; int i; int j; if (datasz != WALL_DIM * WALL_DIM) { Warning ("WA10", "Wall %s: size not %d", lump_name (name), WALL_DIM * WALL_DIM); return 0; } for (i = 1; i < WALL_DIM; i++) { for (j = i; j < WALL_DIM; j++) { char swap = *d; /* Swap (*s) and (*d) */ *d = *s; *s = swap; s++; d += WALL_DIM; } s += 1 + i; d = s + WALL_DIM - 1; } return 0; } /******************* End ROTT wall module ************************/ /* color index convertion bmp->doom */ static UInt8 Idx2Doom[256]; /******************* BMP module ************************/ struct BMPPALET { UInt8 B; UInt8 G; UInt8 R; UInt8 Zero;}; struct BMPPIXEL { UInt8 B; UInt8 G; UInt8 R;}; /* ** bitmap conversion */ struct BMPHEAD { Int32 bmplen; /*02 total file length Size*/ Int32 reserved; /*06 void Reserved1 Reserved2*/ Int32 startpix; /*0A start of pixels OffBits*/ /*bitmap core header*/ Int32 headsz; /*0E Size =nb of bits in bc header*/ Int32 szx; /*12 X size = width Int16 width*/ Int32 szy; /*16 Y size = height Int16 height*/ Int32 planebits; /*1A equal to 1 word planes*/ /*1C nb of bits word bitcount 1,4,8,24*/ /**/ Int32 compress; /*1E Int32 compression = BI_RGB = 0*/ Int32 pixlen; /*22 Int32 SizeImage size of array necessary for pixels*/ Int32 XpixRes; /*26 XPelsPerMeter X resolution no one cares*/ Int32 YpixRes; /*2A YPelPerMeter Y resolution but code1a=code1b*/ Int32 ColorUsed; /*2C ClrUsed nb of colors in palette*/ Int32 ColorImp; /*32 ClrImportant nb of important colors in palette*/ /*palette pos: ((UInt8 *)&headsz) + headsz */ /*palette size = 4*nb of colors. order is Blue Green Red (Black? always0)*/ /*bmp line size is xsize*bytes_per_pixel aligned on Int32 */ /*pixlen = ysize * line size */ }; /* ** BMP to RAW conversion ** ** in: UInt8 *bmp; Int32 bmpsize; UInt8 COLindex(R,G,B); ** ** out: UInt8 *raw; Int16 rawX; Int16 rawY; */ static char *BMPtoRAW(Int16 *prawX,Int16 *prawY,char *file) { struct BMPHEAD *head; /*bmp header*/ struct BMPPALET *palet; /*palet. 8 bit*/ Int32 paletsz; UInt8 *line; /*line of BMP*/ Int32 startpix,linesz=0; struct BMPPIXEL *pixs; /*pixels. 24 bit*/ UInt8 *bmpidxs; /*color indexs in BMP 8bit*/ Int16 szx,szy,x,y,p,nbits; Int32 ncols; Int32 bmpxy; char *raw; /*point to pixs. 8 bit*/ Int32 rawpos; UInt8 col='\0'; FILE *fd; char sig[2]; /* ** read BMP header for size */ fd=fopen(file,FOPEN_RB); if(fd==NULL) ProgError("BR10", "%s: %s", fname (file), strerror (errno)); if(fread(sig,2,1,fd)!=1) ProgError("BR11", "%s: read error in header", fname (file)); if(strncmp(sig,"BM",2)!=0) ProgError("BR12", "%s: bad BMP magic", fname (file)); head=(struct BMPHEAD *)Malloc(sizeof(struct BMPHEAD)); if(fread(head,sizeof(struct BMPHEAD),1,fd)!=1) ProgError("BR13", "%s: read error in header", fname (file)); /* ** check the BMP header */ if (peek_i32_le (&head->compress) != 0) ProgError("BR14", "%s: not an RGB BMP", fname (file)); read_i32_le (&head->startpix, &startpix); szx = (Int16) peek_i32_le (&head->szx); szy = (Int16) peek_i32_le (&head->szy); if(szx<1) ProgError("BR15", "%s: bad width", fname (file)); if(szy<1) ProgError("BR16", "%s: bad height", fname (file)); ncols = peek_i32_le (&head->ColorUsed); /* ** Allocate memory for raw bytes */ raw=(char *)Malloc(((Int32)szx)*((Int32)szy)); /* ** Determine line size and palet (if needed) */ nbits = (Int16) ((peek_i32_le (&head->planebits)>>16)&0xFFFFL); switch(nbits) { case 24: /*RGB, aligned mod 4*/ linesz=((((Int32)szx)*sizeof(struct BMPPIXEL))+3L)&~3L; break; case 8: linesz=(((Int32)szx)+3L)&~3L; /*Idx, aligned mod 4*/ if(ncols>256) ProgError("BR17", "%s: palette should have 256 entries", fname (file)); if(ncols<=0) ncols=256; /*Bug of PaintBrush*/ paletsz=(ncols)*sizeof(struct BMPPALET); /*set position to palette (a bit hacked)*/ if(fseek(fd,0xEL+peek_i32_le(&head->headsz),SEEK_SET)) ProgError("BR18", "%s: can't seek to BMP palette (%s)", fname (file), strerror (errno)); /* FIXME mention the destination offset */ /*load palette*/ palet=(struct BMPPALET *)Malloc(paletsz); if(fread(palet,(size_t)paletsz,1,fd)!=1) ProgError("BR19", "%s: can't read palette", fname (file)); for(p=0;ppixlenbmplen)<(startpix+bmpxy)) ProgError("BR21", "%s: size of pixel area incorrect", fname (file)); Free(head); /* seek start of pixels */ if(fseek(fd,startpix,SEEK_SET)) ProgError("BR22", "%s: can't seek to pixel data (%s)", fname (file), strerror (errno)); /* FIXME mention the destination offset */ /* read lines */ line = (UInt8 *)Malloc(linesz); bmpidxs=(UInt8 *)line; pixs=(struct BMPPIXEL *)line; /*convert bmp pixels/bmp indexs into doom indexs*/ for(y=szy-1;y>=0;y--) { if(fread(line,(size_t)linesz,1,fd)!=1) ProgError("BR23", "%s: read error in pixel data", fname (file)); for(x=0;xbmplen, bmplen); write_i32_le (&head->reserved, 0); write_i32_le (&head->startpix, startpix); write_i32_le (&head->headsz, 0x28); write_i32_le (&head->szx, rawX); write_i32_le (&head->szy, rawY); write_i32_le (&head->planebits, 0x80001);/*1 plane 8bits BMP*/ write_i32_le (&head->compress, 0); /* RGB */ write_i32_le (&head->pixlen, pixlen); write_i32_le (&head->XpixRes, 0); write_i32_le (&head->YpixRes, 0); write_i32_le (&head->ColorUsed, ncol); write_i32_le (&head->ColorImp, ncol); if(fwrite(head,sizeof(struct BMPHEAD),1,fd)!=1) ProgError("BW12", "%s: write error", fname (file)); Free(head); /* ** set palette ** */ palet=(struct BMPPALET *)Malloc(paletsz); for(x=0;x=0;y--) { for(x=0;x>3)&0xE)+1); GifScreen.Backgnd = GifHead.backgnd; GifScreen.AspRatio = GifHead.aspratio; Memset(GifColor,0,256*sizeof(struct PIXEL)); /* read Global Color Map */ if ((GifHead.info)&COLORMAP) { if(fread(GifColor,sizeof(struct PIXEL),bitPixel,fd)!=bitPixel) { fclose(fd); ProgError ("GR14", "%s: read error in GIF data", fname (file)); } } /* ** Read extension, images, etc... */ while((c=getc(fd)) !=EOF) { if(c==';') break; /* GIF terminator */ /*no need to test imagecount*/ if(c=='!') /* Extension */ GIFextens(fd); else if(c==',') /*valid image start*/ { if(raw!=NULL) /* only keep first image*/ { Warning("GR15", "%s: other GIF images discarded", fname (file)); break; } if (fread_i16_le (fd, &GifImage.ofsx) || fread_i16_le (fd, &GifImage.ofsy) || fread_i16_le (fd, &GifImage.xsize) || fread_i16_le (fd, &GifImage.ysize) || (chr = fgetc (fd), GifHead.info = chr, chr == EOF)) { fclose(fd); ProgError ("GR16", "%s: read error", fname (file)); } /* GifImage.ofsx,ofsy X,Y offset ignored */ bitPixel = 1<<((GifImage.info&0x07)+1); IntLace= (GifImage.info & INTERLACE)? TRUE:FALSE; Xsz = GifImage.xsize; Ysz = GifImage.ysize; if((Xsz<1)||(Ysz<1)) { fclose(fd); ProgError ("GR17", "%s: bad size", fname (file)); } if(GifImage.info & COLORMAP) { if(fread(GifColor,sizeof(struct PIXEL),bitPixel,fd)!=bitPixel) { fclose(fd); ProgError ("GR18", "%s: read error", fname (file)); } } /*read the GIF. if many pictures, only the last one is kept. */ raw= GIFreadPix(fd, Xsz,Ysz); } /*else, not a valid start character, skip to next*/ } fclose(fd); if(raw == NULL) ProgError ("GR19", "%s: no picture found", fname (file)); /*convert colors*/ for (c=0; c<256; c++) { Idx2Doom[c]=(UInt8)COLindex((UInt8)GifColor[c].R,(UInt8)GifColor[c].G,(UInt8)GifColor[c].B,(UInt8)c); } rawSz=((Int32)Xsz) * ((Int32)Ysz); for (rawpos=0; rawpos> 2) & 0x7; Gif89.InputFlag = (Buf[0] >> 1) & 0x1; Gif89.DelayTime = ((Buf[2]<<8)&0xFF00) + Buf[1]; if(Buf[0] & 0x1)Gif89.Transparent = Buf[3]; break; default: /*Unknown GIF extension*/ break; } while (GIFreadBlock(fd, Buf)>0); } /* ** Read Gif Indexes */ static char *GIFreadPix(FILE *fd,Int16 Xsz,Int16 Ysz) { char *raw=NULL; Int32 rawSz; #if NEWGIFD #else Int16 v; Int32 rawpos; unsigned char c=0; #endif /* ** get some space */ rawSz = ((Int32)Xsz)*((Int32)Ysz); raw = (char *)Malloc(rawSz); #if NEWGIFD InitDecoder( fd, 8, Xsz); Decode((UInt8 *)raw, rawSz); ExitDecoder(); #else /* Initialize the Compression routines */ if (fread(&c,1,1,fd)!=1) ProgError("GR50", "GIF: read error" ); if (LWZReadByte(fd, TRUE, c) < 0) ProgError("GR51", "GIF: bad code in image" ); /* read the file */ for(rawpos=0;rawpos=0); /* ignore extra data */ #endif return raw; } /* ** Un-Interlace a GIF */ static char *GIFintlace(char *org,Int16 Xsz,Int16 Ysz) { Int32 rawpos,orgpos; Int16 pass,Ys=0,Y0=0,y; char *raw; rawpos = ((Int32)Xsz)*((Int32)Ysz); raw = (char *)Malloc(rawpos); orgpos = 0; for(pass=0;pass<4;pass++) { switch(pass) { case 0: Y0=0; Ys=8; break; case 1: Y0=4; Ys=8; break; case 2: Y0=2; Ys=4; break; case 3: Y0=1; Ys=2; break; } rawpos=(Int32)Y0*(Int32)Xsz; for(y=Y0;y=CountTop) return EOF; c=Raw[ CountCur]; CountCur++; return ((code_int)c &0xFF); } #endif static void RAWtoGIF (char *file, char *raw, Int16 rawX, Int16 rawY, struct PIXEL *doompal ) { FILE *fd; Int32 rawSz; fd=fopen(file,FOPEN_WB); if (fd==NULL) ProgError("GW10", "%s: %s", fname (file), strerror (errno)); rawSz = (Int32)rawX * (Int32)rawY; /* screen header */ strncpy(GifIdent,"GIF87a",6); fwrite(GifIdent, 1, 6, fd ); /*header*/ fwrite_u16_le (fd, rawX); /* xsize */ fwrite_u16_le (fd, rawY); /* ysize */ fputc (COLORMAP | ((8 - 1) << 4) | (8 - 1), fd); /* info */ /* global colormap, 256 colors, 7 bit per pixel*/ fputc (0, fd); /* backgnd */ fputc (0, fd); /* aspratio */ fwrite(doompal,sizeof(struct PIXEL),256,fd); /*color map*/ fputc (',',fd); /*Image separator*/ /* image header */ fwrite_u16_le (fd, 0); /* ofsx */ fwrite_u16_le (fd, 0); /* ofsy */ fwrite_u16_le (fd, rawX); /* xsize*/ fwrite_u16_le (fd, rawY); /* ysize */ fputc (0, fd); /* info */ /* image data */ fputc(8,fd); /* Write out the initial code size */ #if NEWGIFE InitEncoder(fd,8); Encode((UInt8 *)raw,rawSz); ExitEncoder(); #else Raw = raw; /* init */ CountTop = rawSz; CountCur = 0; compressInit(); compress( 8+1, fd, NextPixel ); /* write picture, InitCodeSize=8 */ compressFree(); #endif /* termination */ fputc(0,fd); /*0 length packet to end*/ fputc(';',fd); /*GIF file terminator*/ if (fclose(fd)) ProgError ("GW11", "%s: %s", fname (file), strerror (errno)); } /******************* End GIF module ************************/ #endif /*DeuTex*/ deutex-4.4.902/src/sound.c0000644000324500032450000004050410304422475014657 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include "tools.h" #include "endianm.h" #include "mkwad.h" #include "sound.h" #include "text.h" /*compile only for DeuTex*/ #if defined DeuTex /*********************** WAVE *********************/ static struct RIFFHEAD { char riff[4]; Int32 length; char wave[4]; } headr; static struct CHUNK { char name[4]; Int32 size; } headc; static struct WAVEFMT/*format*/ { char fmt[4]; /* "fmt " */ Int32 fmtsize; /*0x10*/ Int16 tag; /*format tag. 1=PCM*/ Int16 channel; /*1*/ Int32 smplrate; Int32 bytescnd; /*average bytes per second*/ Int16 align; /*block alignment, in bytes*/ Int16 nbits; /*specific to PCM format*/ }headf; static struct WAVEDATA /*data*/ { char data[4]; /* "data" */ Int32 datasize; }headw; static void SNDsaveWave(char *file,char *buffer,Int32 size,Int32 speed) { FILE *fp; Int32 wsize,sz=0; fp=fopen(file,FOPEN_WB); if(fp==NULL) { ProgError("RW10", "%s: %s", fname (file), strerror (errno)); } /*header*/ strncpy(headr.riff,"RIFF",4); write_i32_le (&headr.length, 4+sizeof(struct WAVEFMT)+sizeof(struct WAVEDATA)+size); strncpy(headr.wave,"WAVE",4); fwrite(&headr,sizeof(struct RIFFHEAD),1,fp); strncpy(headf.fmt, "fmt ",4); write_i32_le (&headf.fmtsize, sizeof(struct WAVEFMT)-8); write_i16_le (&headf.tag, 1); write_i16_le (&headf.channel, 1); write_i32_le (&headf.smplrate, speed); write_i32_le (&headf.bytescnd, speed); write_i16_le (&headf.align, 1); write_i16_le (&headf.nbits, 8); fwrite(&headf,sizeof(struct WAVEFMT),1,fp); strncpy(headw.data,"data",4); write_i32_le (&headw.datasize, size); fwrite(&headw,sizeof(struct WAVEDATA),1,fp); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE:(size-wsize); if(fwrite((buffer+(wsize)),(size_t)sz,1,fp)!=1) ProgError("RW11", "%s: write error", fname (file)); } fclose(fp); } char *SNDloadWaveFile(char *file, Int32 *psize, Int32 *pspeed) { FILE *fp; Int32 wsize,sz=0,smplrate,datasize; Int32 chunk; char *data; fp=fopen(file,FOPEN_RB); if(fp==NULL) ProgError("RR10", "%s: %s", fname (file), strerror (errno)); /*read RIFF HEADER*/ if(fread(&headr,sizeof(struct RIFFHEAD),1,fp)!=1) ProgError("RR11", "%s: read error in header", fname (file)); /*check RIFF header*/ if(strncmp(headr.riff,"RIFF",4)!=0) ProgError("RR12", "%s: bad RIFF magic in header (%s)", fname (file), short_dump (headr.riff, 4)); if(strncmp(headr.wave,"WAVE",4)!=0) ProgError("RR13", "%s: bad WAVE magic in header (%s)", fname (file), short_dump (headr.wave, 4)); chunk=sizeof(struct RIFFHEAD); for(sz=0;;sz++) { if(sz>256) ProgError("RR14", "%s: no fmt", fname (file)); fseek(fp,chunk,SEEK_SET); if(fread(&headc,sizeof(struct CHUNK),1,fp)!=1) ProgError("RR15", "%s: no fmt", fname (file)); if(strncmp(headc.name,"fmt ",4)==0)break; /* There used to be a bug here; sizeof (struct CHUNK) had its bytes swapped too. Reading .wav files on big endian machines must have been broken. -- AYM 1999-07-04 */ chunk += sizeof (struct CHUNK) + peek_i32_le (&headc.size); } fseek(fp,chunk,SEEK_SET); fread(&headf,sizeof(struct WAVEFMT),1,fp); if(peek_i16_le (&headf.tag)!=1) ProgError("RR16", "%s: not raw data", fname (file)); if(peek_i16_le (&headf.channel)!=1) ProgError("RR17", "%s: not one channel", fname (file)); smplrate=peek_i32_le(&headf.smplrate); for(sz=0;;sz++) { if(sz>256) ProgError("RR18", "%s: no data", fname (file)); fseek(fp,chunk,SEEK_SET); if(fread(&headc,sizeof(struct CHUNK),1,fp)!=1) ProgError("RR19", "%s: no data", fname (file)); if(strncmp(headc.name,"data",4)==0)break; /* Same endianness bug as above. */ chunk += sizeof (struct CHUNK) + peek_i32_le (&headc.size); } fseek(fp,chunk,SEEK_SET); if(fread(&headw,sizeof(struct WAVEDATA),1,fp)!=1) ProgError("RR20", "%s: no data", fname (file)); datasize = peek_i32_le (&headw.datasize); /*check WAVE header*/ if(datasize>0x1000000L) /* AYM 2000-04-22 */ ProgError("RR21", "%s: sample too long (%ld)", fname (file), (long) datasize); /*read data*/ data=(char *)Malloc(datasize); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE:(datasize-wsize); if(fread((data+(wsize)),(size_t)sz,1,fp)!=1) ProgError("RR22", "%s: read error in data", fname (file)); } fclose(fp); *psize=datasize; *pspeed=smplrate&0xFFFFL; return data; } /***************** AU **********************/ struct AUHEAD { char snd[4]; /* ".snd" */ Int32 dataloc; /* Always big endian */ Int32 datasize; /* Always big endian */ Int32 format; /* Always big endian */ Int32 smplrate; /* Always big endian */ Int32 channel; /* Always big endian */ char info[4]; }; static struct AUHEAD heada; /*char data[datasize] as signed char*/ static void SNDsaveAu(char *file,char *buffer,Int32 size,Int32 speed) { FILE *fp; Int32 i,wsize,sz=0; fp=fopen(file,FOPEN_WB); if(fp==NULL) ProgError("AW10", "%s: %s", fname (file), strerror (errno)); /*header*/ strncpy(heada.snd,".snd",4); write_i32_be (&heada.dataloc, sizeof (struct AUHEAD)); write_i32_be (&heada.datasize, size); write_i32_be (&heada.format, 2); /*8 bit linear*/ write_i32_be (&heada.smplrate, speed); write_i32_be (&heada.channel, 1); heada.info[0]='\0'; if(fwrite(&heada,sizeof(struct AUHEAD),1,fp)!=1) ProgError("AW11", "%s: write error", fname (file)); for(i=0;iMEMORYCACHE)? MEMORYCACHE:(size-wsize); if(fwrite((buffer+(wsize)),(size_t)sz,1,fp)!=1) ProgError("AW12", "%s: write error", fname (file)); } fclose(fp); } char *SNDloadAuFile(char *file, Int32 *psize, Int32 *pspeed) { FILE *fp; Int32 wsize,sz=0,i,smplrate,datasize; char *data; fp=fopen(file,FOPEN_RB); if(fp==NULL) ProgError("AR10", "%s: %s", fname (file), strerror (errno)); /*read AU HEADER*/ if(fread(&heada,sizeof(struct AUHEAD),1,fp)!=1) ProgError("AR11", "%s: read error in header", fname (file)); /*check AU header*/ if(strncmp(heada.snd,".snd",4)!=0) ProgError ("AR12", "%s: bad magic in header (%s)", fname (file), short_dump (heada.snd, 4)); if(peek_i32_be (&heada.format) != 2) ProgError("AR13", "%s: not linear 8 bit", fname (file)); if(peek_i32_be (&heada.channel)!= 1) ProgError("AR14", "%s: not one channel", fname (file)); if (fseek (fp, peek_i32_be (&heada.dataloc), SEEK_SET)) ProgError("AR15", "%s: bad header", fname (file)); smplrate = peek_i32_be (&heada.smplrate); datasize = peek_i32_be (&heada.datasize); /*check header*/ if(datasize>0x100000L) ProgError("AR16", "%s: sample too long (%ld)", fname (file), (long) datasize); /*read data*/ data=(char *)Malloc(datasize); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE:(datasize-wsize); if(fread((data+(wsize)),(size_t)sz,1,fp)!=1) ProgError("AR17", "%s: read error in data", fname (file)); } fclose(fp); /*convert from signed to unsigned char*/ for(i=0;i>8)&0xFFL); blockv.sizeU= (char)((sz>>16)&0xFFL); if(speed<=4000)speed=4000; blockv.rate=(char)(256-(1000000L/((long)speed))); blockv.cmprs=0; fwrite(&blockv,sizeof(struct VOCBLOCK1),1,fp); /*VOC data*/ for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE:(size-wsize); if(fwrite((buffer+(wsize)),(size_t)sz,1,fp)!=1) ProgError("VW11", "%s: write error", fname (file)); } blockv.type=0;/*last block*/ fwrite(&blockv,1,1,fp); fclose(fp); } char *SNDloadVocFile(char *file, Int32 *psize, Int32 *pspeed) { FILE *fp; Int32 wsize,sz=0,smplrate,datasize; char *data; fp=fopen(file,FOPEN_RB); if(fp==NULL) ProgError("VR10", "%s: %s", fname (file), strerror (errno)); /*read VOC HEADER*/ if(fread(&headv,sizeof(struct VOCHEAD),1,fp)!=1) ProgError("VR11", "%s: read error in header", fname (file)); if(strncmp(VocId,headv.ident,VOCIDLEN)!=0) ProgError("VR12", "%s: bad magic", fname (file)); if(fseek(fp,headv.block1,SEEK_SET)) ProgError("VR13", "%s: bad header", fname (file)); if(fread(&blockv,sizeof(struct VOCHEAD),1,fp)!=1) ProgError("VR14", "%s: read error in first block", fname (file)); if(blockv.type!=1) ProgError("VR15", "%s: first block is not sound", fname (file)); datasize= ((blockv.sizeU)<<16)&0xFF0000L; datasize+=((blockv.sizeM)<<8)&0xFF00L; datasize+= (blockv.sizeL)&0xFFL; datasize -=2; /*check VOC header*/ if(datasize>0x10000L) ProgError("VR16", "%s: sample too long", fname (file)); if(blockv.cmprs!=0) ProgError("VR17", "%s: compression not supported", fname (file)); smplrate= (1000000L)/(256-(((int)blockv.rate)&0xFF)); /*read data*/ data=(char *)Malloc(datasize); for(wsize=0;wsizeMEMORYCACHE)? MEMORYCACHE:(datasize-wsize); if(fread((data+(wsize)),(size_t)sz,1,fp)!=1) ProgError("VR18", "%s: read error in data", fname (file)); } fclose(fp); /*should check for more blocks*/ *psize=datasize; *pspeed=smplrate&0xFFFFL; return data; } /**************** generic sound *******************/ void SNDsaveSound (char *file, char *buffer, Int32 size, SNDTYPE format, Bool fullsnd, const char *name) { char *data; Int32 datasize; Int32 phys_size; Int16 type; Int16 headsize; UInt16 rate; headsize = sizeof (Int16) + sizeof (Int16) + sizeof (Int32); if (size < headsize) { Warning ("SD10", "Sound %s: lump has no header, skipping", lump_name (name)); return; } type = peek_i16_le (buffer); rate = peek_u16_le (buffer + 2); datasize = peek_i32_le (buffer + 4); data = buffer + headsize; if (type!=3) Warning ("SD11", "Sound %s: weird type %d, extracting anyway", lump_name (name), type); phys_size = size - headsize; if (datasize > phys_size) { Warning ("SD12", "Sound %s: declared length %lu > lump size %lu, truncating", lump_name (name), (unsigned long) datasize, (unsigned long) phys_size); datasize = phys_size; } /* Sometimes the size of sound lump is greater than the declared sound size. */ else if (datasize < phys_size) { if (fullsnd == TRUE) /* Save entire lump */ datasize = phys_size; else { Warning ("SD13", "Sound %s: lump size %lu > declared length %lu, truncating", lump_name (name), (unsigned long) datasize, (unsigned long) phys_size); } } switch (format) { case SNDWAV: SNDsaveWave (file,data,datasize,rate); break; case SNDAU: SNDsaveAu (file,data,datasize,rate); break; case SNDVOC: SNDsaveVoc (file,data,datasize,rate); break; default: Bug ("SD14", "sndsv %d", (int) format); } } Int32 SNDcopyInWAD (struct WADINFO *info, char *file, SNDTYPE format) { Int32 size = 0; Int32 datasize; Int32 rate; char *data = NULL; long wadrate; switch (format) { case SNDWAV: data = SNDloadWaveFile (file, &datasize, &rate); break; case SNDAU: data = SNDloadAuFile (file, &datasize, &rate); break; case SNDVOC: data = SNDloadVocFile (file, &datasize, &rate); break; default: Bug ("SC10", "sndcw %d", (int) format); } wadrate = rate; switch (rate_policy) { case RP_REJECT: if (rate != 11025) ProgError ("SC11", "%s: sample rate not 11025 Hz", fname (file)); break; case RP_FORCE: if (rate > 11025) { Warning("SC12", "%s: resampling down from %ld Hz to 11025 Hz", fname (file), rate); wadrate = 11025; { double ratio = 11025.0 / rate; long s; datasize = (Int32) (ratio * datasize) + 1; for (s = 0; s < datasize; s++) data[s] = data[(size_t) (s / ratio + 0.5)]; } data = (char *) Realloc (data, datasize); } else if (rate < 11025) { Warning("SC13", "%s: resampling up from %ld Hz to 11025 Hz", fname (file), rate); wadrate = 11025; { double ratio = 11025.0 / rate; long s; datasize = (Int32) (ratio * datasize) + 1; data = (char *) Realloc (data, datasize); for (s = datasize - 1; s >= 0; s--) data[s] = data[(size_t) (s / ratio + 0.5)]; } } break; case RP_WARN: if (rate != 11025) Warning ("SC14", "%s: sample rate != 11025 Hz, won't work on Doom < 1.4", fname (file)); break; case RP_ACCEPT: break; default: Bug ("SC15", "SNDcopyInWAD: rate_policy %d", (int) rate_policy); } if (datasize > 0) { size = WADRwriteShort (info, 3); size += WADRwriteShort (info, wadrate); size += WADRwriteLong (info, datasize); size += WADRwriteBytes (info, data, datasize); } Free (data); return size; } /*********** PC speaker sound effect ***********/ void SNDsavePCSound(const char *lumpname, const char *file, const char *buffer, Int32 size) { FILE *fp; const char *data; Int16 datasize,type,headsize; Int16 i; headsize = sizeof(Int16)+sizeof(Int16); if(size255)) ProgError("KR11", "%s: number out of bounds [0-255]", fname (file)); datasize+=sizeof(char); c=(char)(s&0xFF); size+=WADRwriteBytes(info,&c,sizeof(c)); } WADRsetShort(info,datasizepos,datasize); TXTcloseR(Txt); return size; } #endif /*DeuTex*/ deutex-4.4.902/src/sscript.c0000644000324500032450000001432610304422602015211 0ustar aymaym00000000000000/* * sscript.c - read and write Strife scripts * AYM 2000-05-13 */ /* This file is copyright André Majorel 2000-2005. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include #include "mkwad.h" #include "tools.h" #include "endianm.h" #include "sscript.h" #define PAGESZ 1516 #define OPTIONSZ 228 enum field_type_t { FT_I32, FT_NAME, FT_S16, FT_S32, FT_S80, FT_S320 }; static void dump_field (FILE *fp, const unsigned char *buf, unsigned long *ofs, enum field_type_t type, const char *desc); static void dump_junk (FILE *fp, const unsigned char *buf, unsigned long *ofs, size_t nbytes, const char *desc); static int mem_is_zero (const char *buf, size_t buf_size); /* * sscript_save - save a script lump to file */ int sscript_save (struct WADINFO *wad, Int16 n, const char *file) { FILE *fp = NULL; unsigned char *data = NULL; Int32 size = 0; const char *lumpname = wad->dir[n].name; data = (unsigned char *) WADRreadEntry (wad, n, &size); if (size % PAGESZ) { Warning ("SS10", "script %s: weird size %ld", lump_name (lumpname), (long) size); size = PAGESZ * (size / PAGESZ); } fp = fopen (file, "w"); if (fp == NULL) { nf_err ("SS15", "%s: %s", file, strerror (errno)); return 1; } fprintf (fp, "# DeuTex Strife script source version 1\n"); /* Save all pages */ { int p; for (p = 0; p < size / PAGESZ; p++) { unsigned long ofs = PAGESZ * p; int o; fputc ('\n', fp); #ifdef SHOW_OFFSETS fprintf (fp, "/* %05lXh */ ", ofs); #endif fprintf (fp, "page %d {\n", p); dump_field (fp, data, &ofs, FT_I32, " unknown0 "); dump_field (fp, data, &ofs, FT_I32, " unknown1 "); dump_field (fp, data, &ofs, FT_I32, " unknown2 "); dump_field (fp, data, &ofs, FT_I32, " unknown3 "); dump_field (fp, data, &ofs, FT_I32, " unknown4 "); dump_field (fp, data, &ofs, FT_I32, " unknown5 "); dump_field (fp, data, &ofs, FT_S16, " character "); dump_field (fp, data, &ofs, FT_NAME, " voice "); dump_field (fp, data, &ofs, FT_NAME, " background "); dump_field (fp, data, &ofs, FT_S320, " statement "); for (o = 0; o < 5; o++) { /* If the option is zeroed out, omit it */ if (mem_is_zero ((char *) (data + ofs), OPTIONSZ)) { ofs += OPTIONSZ; continue; } /* Else, decode it */ fputc ('\n', fp); #ifdef SHOW_OFFSETS fprintf (fp, "/* %05lXh */ ", ofs); #endif fprintf (fp, " option %d {\n", o); dump_field (fp, data, &ofs, FT_I32, " whata "); dump_field (fp, data, &ofs, FT_I32, " whatb "); dump_field (fp, data, &ofs, FT_I32, " whatc "); dump_field (fp, data, &ofs, FT_I32, " whatd "); dump_field (fp, data, &ofs, FT_I32, " whate "); dump_field (fp, data, &ofs, FT_I32, " price "); dump_field (fp, data, &ofs, FT_I32, " whatg "); dump_field (fp, data, &ofs, FT_S32, " option "); dump_field (fp, data, &ofs, FT_S80, " success "); dump_field (fp, data, &ofs, FT_I32, " whath "); dump_field (fp, data, &ofs, FT_I32, " whati "); dump_field (fp, data, &ofs, FT_S80, " failure "); #ifdef SHOW_OFFSETS fprintf (fp, "/* %05lXh */ ", ofs); #endif fputs (" }\n", fp); } #ifdef SHOW_OFFSETS fprintf (fp, "/* %05lXh */ ", ofs); #endif fputs ("}\n", fp); /* Sanity check */ if (ofs % PAGESZ) Bug ("SS20", "script %s: page %d: bad script offset %d", lump_name (lumpname), p, (int) ofs); } } Free (data); if (fclose (fp)) { nf_err ("SS45", "%s: %s", file, strerror (errno)); return 1; } return 0; } /* * sscript_load */ int sscript_load (void) { printf ("Oops! sscript_load not written yet!\n"); return 1; } /* * dump_field - write a field of a page to file */ static void dump_field (FILE *fp, const unsigned char *buf, unsigned long *ofs, enum field_type_t type, const char *desc) { #ifdef SHOW_OFFSETS fprintf (fp, "/* %05lXh */ ", (unsigned long) *ofs); #endif fprintf (fp, "%-10s ", desc); if (type == FT_I32) { fprintf (fp, "%ld", (long) peek_i32_le (buf + *ofs)); *ofs += 4; } else if (type == FT_NAME) { int n; putc ('"', fp); for (n = 0; n < 8 && buf[*ofs + n] != '\0'; n++) putc (tolower (buf[*ofs + n]), fp); putc ('"', fp); *ofs += 8; } else if (type == FT_S16) { fprintf (fp, "\"%.16s\"", buf + *ofs); *ofs += 16; } else if (type == FT_S32) { fprintf (fp, "\"%.32s\"", buf + *ofs); *ofs += 32; } else if (type == FT_S80) { fprintf (fp, "\"%.80s\"", buf + *ofs); *ofs += 80; } else if (type == FT_S320) { fprintf (fp, "\"%.320s\"", buf + *ofs); *ofs += 320; } else { Bug ("SS25", "bad field type %d", (int) type); } fputs (";\n", fp); } /* * dump_junk - dump 32-bit little-endian integer at buf */ static void dump_junk (FILE *fp, const unsigned char *buf, unsigned long *ofs, size_t nbytes, const char *desc) { int n; const int BPL = 16; for (n = 0; n < nbytes; n++) { if (n % BPL == 0) { #ifdef SHOW_OFFSETS fprintf (fp, "/* %05lXh */ ", (unsigned long) *ofs); #endif if (n == 0) fprintf (fp, "%-10s `", desc); else fprintf (fp, "%-10s ", ""); } else putc (' ', fp); fprintf (fp, "%02X", buf[*ofs + n]); if (n + 1 >= nbytes) fputs ("`;\n", fp); else if (n % BPL == BPL - 1) putc ('\n', fp); } *ofs += nbytes; } static int mem_is_zero (const char *buf, size_t buf_size) { int n; for (n = 0; n < buf_size; n++) if (buf[n] != '\0') return 0; return 1; } deutex-4.4.902/src/substit.c0000644000324500032450000001077710304423004015222 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include "tools.h" /*compile only for DeuTex*/ #if defined DeuTex /****** DOOM EXE hacking module *********************/ /* Int16 const RAWSIZE = 0x2000; Int16 const STRMAX = 256; Int16 const SHOWPRGRS = 0x4000; void EXE2list(FILE *out,char *doomexe,Int32 start,Int16 thres) { FILE *exe; char *raw; Int16 iraw,remains; char *str; Int16 istr,count; Int16 c; Int32 lastpos,posit; Int32 found=0; count=0; lastpos = posit=start; iraw=0;raw= (char *)Malloc(RAWSIZE*sizeof(char)); istr=0;str= (char *)Malloc((STRMAX+2)*sizeof(char)); exe=fopen(doomexe,FOPEN_RB); if(exe==NULL)ProgError("XX99", "Can't open %s",doomexe); if(fseek(exe,posit,SEEK_SET))ProgError("XX99", "Can't seek in %s",doomexe); TXTinit(); for(iraw=0,remains=0;;remains--,iraw++) { if(remains==0) { remains=fread(raw,1,RAWSIZE,exe); iraw=0;} if(remains<=0) break; c=raw[iraw]; posit++; switch(TXTvalid(c)) { case 1: count++; str[istr]=c; istr=(count=thres) { fprintf(out,"let: #%s#\n be: #%s#\n\n",str,str); found++; } if(posit>lastpos+SHOWPRGRS) { lastpos=posit; Phase("XX99", "Current offset:0x%-6lx\tfound %ld strings",posit,found); } default: count=0; istr=0; } #ifdef WinDeuTex windoze(); #endif } Free(raw); Free(str); } void EXEsubstit(char *texin,char *doomexe,Int32 start,Int16 thres) { FILE *exe; char *raw; Int16 iraw,remains; char *str; Int16 strln,istr; char *anew; Int16 anewln; Int32 found; Int16 c; Int16 ref; Int32 lastpos,posit; Bool similar,same; struct TXTFILE *TXT; TXT=TXTopen(texin); iraw=0;raw= (char *)Malloc(RAWSIZE*sizeof(char)); istr=0;str= (char *)Malloc((STRMAX+2)*sizeof(char)); anew = (char *)Malloc((STRMAX+2)*sizeof(char)); exe=fopen(doomexe,FOPEN_RBP); if(exe==NULL) ProgError("XX99", "Can't open %s for writing",doomexe); while(1) { strln=STRMAX; anewln=STRMAX; if(TXTboundStrings(TXT,str,&strln,anew,&anewln)!=TRUE) break; if(strln=0) { Warning("XX99", "String defined twice: #%s#",str); found=0;break; } found=lastpos; } } same=similar=FALSE;istr=0;ref=str[istr]; } #ifdef WinDeuTex windoze(); #endif } if(found>0) { Detail("Writing at\t0x%-6lx\t#%s#\n",found,anew); if(fseek(exe,found,SEEK_SET)) ProgError("XX99", "Can't seek %s",doomexe); if(fwrite(anew,1,strln,exe)!=strln) ProgError("XX99", "Can't write %s correctly",doomexe); } else Warning("XX99", "Can't insert #%s#",anew); } fclose(exe); Free(raw); Free(str); Free(anew); TXTclose(TXT); } */ #endif /*DeuTex*/ deutex-4.4.902/src/text.c0000644000324500032450000003411610304423017014506 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* ** This code should contain all the tricky O/S related ** functions. If you're porting DeuTex/DeuSF, look here! */ #include "deutex.h" #include #include "tools.h" #include "text.h" #include /*compile only for DeuTex*/ #if defined DeuTex /* A special instance of struct TXTFILE that is treated by the TXT*() output functions as the equivalent of /dev/null. Writing into it is a no-op. This convention is _not_ supported by the input functions ! */ struct TXTFILE TXTdummy; /*****************************************************/ const Int16 SPACE = 0x2; const Int16 NEWLINE = 0x4; const Int16 COMMENT = 0x8; const Int16 SECTION = 0x10; /*ok for SECTION header*/ const Int16 NAME = 0x20; /*valid as a name identifier*/ const Int16 NUMBER = 0x40; /*valid for a number*/ const Int16 STPATCH = 0x80; /*start of patch?*/ const Int16 EXESTRNG = 0x100; /*valid in #string# */ const Int16 BOUNDARY = 0x200; /*#*/ const Int16 STEQUAL = 0x400; /*=*/ static Int16 TXTval[256]; static Bool TXTok=FALSE; void TXTinit(void) { Int16 n,val; for(n=0;n<256;n++) { val=0; switch(n) { case '#': /*comment,string boundary*/ val |=BOUNDARY+COMMENT;break; case ';': /*comment*/ val |=COMMENT+EXESTRNG;break; case '\0': case '\n': /*newline*/ val |=NEWLINE;break; case '_': /*in name*/ case '\\': /* deal with VILE strange name*/ val |=NAME+EXESTRNG;break; case '[': /* deal with VILE strange name*/ case ']': /* deal with VILE strange name*/ val |=SECTION+NAME+EXESTRNG;break; case '-': case '+': /*in integer number*/ val |=NUMBER+EXESTRNG;break; case '*': /*start of patch wall*/ val |= EXESTRNG+STPATCH;break; case '=': val |= STEQUAL+EXESTRNG;break; case '?': case '!': case '.': case ',': case '\'': case '&': case '(': case ')': case '$': case '%': case '@': case '/': case '<': case '>': case ' ': case '^': case '\"': case ':': val |=EXESTRNG;break; default: break; } if(isdigit(n)) val |= NUMBER+EXESTRNG; if(isalpha(n)) val |= SECTION+NAME+EXESTRNG; if(isspace(n)) val |= SPACE; if (n == '%') /* Deal with Strife's "INVFONG%" and "INVFONY%" */ val |= NAME; TXTval[n]=val; } TXTok=TRUE; } void TXTcloseR(struct TXTFILE *TXT) { if(TXTok!=TRUE) Bug("TR91", "TxtClo"); fclose(TXT->fp); Free(TXT); } struct TXTFILE *TXTopenR(const char *file, int silent) { struct TXTFILE *TXT; size_t pathname_len; /*characters*/ if(TXTok!=TRUE) TXTinit(); pathname_len = strlen (file); TXT = (struct TXTFILE *)Malloc(sizeof(struct TXTFILE) + pathname_len); /*some inits */ strcpy (TXT->pathname, file); TXT->Lines =1;/*start in line 1*/ TXT->SectionStart=0; TXT->SectionEnd =0; TXT->fp = fopen(file,FOPEN_RT); if(TXT->fp==NULL) { if (silent) { Free(TXT); return NULL; } ProgError("TR03", "%s: %s", fname (file), strerror (errno)); } return TXT; } static Bool TXTgetc(struct TXTFILE *TXT,Int16 *c,Int16 *val) { Int16 cc=(Int16)getc(TXT->fp ); TXT->LastChar=cc; if(cc==EOF) return FALSE; *c = cc = (cc&0xFF); *val=TXTval[cc]; if(TXTval[cc]&NEWLINE) TXT->Lines++; return TRUE; } static void TXTungetc(struct TXTFILE *TXT) { Int16 cc=TXT->LastChar; cc = (cc&0xFF); ungetc(cc,TXT->fp); if(TXTval[cc]&NEWLINE) TXT->Lines--; } /*skip lines beginning with # or ; */ Bool TXTskipComment(struct TXTFILE *TXT) { Int16 c=0,val=0; Bool comment; for(comment=FALSE;;) { if(TXTgetc(TXT,&c,&val)!=TRUE)return FALSE; if(val & NEWLINE) /*eat newlines*/ { comment=FALSE; continue;} if(val & COMMENT) /*eat commentaries*/ { comment=TRUE; continue;} if(val & SPACE) /*eat space*/ { continue;} if(comment==FALSE) { TXTungetc(TXT);return TRUE;} } } /* find '*' */ static Bool TXTcheckStartPatch(struct TXTFILE *TXT) { Int16 c=0, val=0; if(TXTgetc(TXT,&c,&val)!=TRUE) return FALSE; if(val & STPATCH) return TRUE; TXTungetc(TXT); return FALSE; } /*read string, skip space before, stop space/\n*/ static Bool TXTread(struct TXTFILE *TXT,char name[8],Int16 valid) { Int16 c=0,val=0,n=0; while(1) { if(TXTgetc(TXT,&c,&val)!=TRUE)return FALSE; if(val & NEWLINE) continue; if(val & SPACE) continue; if(val & valid) break; ProgError("TR11", "%s(%ld): illegal char %s", TXT->pathname, (long) TXT->Lines, quotechar (c)); } name[0]=(char)c; for(n=1; n<256; n++ ) { if(TXTgetc(TXT,&c,&val)!=TRUE) break; if(val&SPACE) { TXTungetc(TXT);break;} if(!(val&valid)) ProgError("TR13", "%s(%ld): illegal char %s in word", TXT->pathname, (long) TXT->Lines, quotechar (c)); if(n<8) name[n]=(char)c; } if(n<8)name[n]='\0'; return TRUE; } Int16 TXTreadShort(struct TXTFILE *TXT) { static char buffer[9]; TXTread(TXT,buffer,NUMBER); buffer[8]='\0'; return (Int16)atoi(buffer); } static Bool TXTboundSection(struct TXTFILE *TXT); static Bool TXTreadIdent(struct TXTFILE *TXT,char name[8]) { if(TXTok!=TRUE) Bug("TR21", "%s: TxtRid", fname (TXT->pathname)); if(TXTskipComment(TXT)==FALSE) return FALSE; /*check end of section*/ if((TXT->Lines)>(TXT->SectionEnd)) { if(TXTboundSection(TXT)==FALSE) return FALSE; /*no other section*/ } if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) ProgError("TR23", "%s(%ld): expected identifier or \"END:\"", TXT->pathname, (long) TXT->Lines); Normalise(name,name); return TRUE; } /* ** STPATCH is also used to indicate repetition */ static Bool TXTreadOptionalRepeat(struct TXTFILE *TXT) { Int16 c=0,val=0; while(1) { if(TXTgetc(TXT,&c,&val)!=TRUE) return FALSE; if(!(val & NEWLINE)) { if(val & STPATCH) break; /*look for STPATCH*/ if(val & SPACE) continue; /*skip space*/ } TXTungetc(TXT); return FALSE; } return TRUE; /*found*/ } /* ** STEQUAL is used to indicate alternate name */ static void TXTreadOptionalName(struct TXTFILE *TXT,char name[8]) { Int16 c=0,val=0; while(1) { if(TXTgetc(TXT,&c,&val)!=TRUE) return; if(!(val & NEWLINE)) { if(val & STEQUAL) continue; /*skip '='*/ if(val & SPACE) continue; /*skip space*/ if(val & (NAME&(~NUMBER))) break; } TXTungetc(TXT); return; /*name is NOT modified*/ } TXTungetc(TXT); if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) { ProgError("TR32", "%s(%ld): invalid optional name", TXT->pathname, (long) TXT->Lines); } } /* ** Read integer if exist before NEWLINE, ** but don't eat NEWLINE */ static Int16 TXTreadOptionalShort(struct TXTFILE *TXT) { static char name[9]; Int16 n,c=0,val=0; while(1) { if(TXTgetc(TXT,&c,&val)!=TRUE)return INVALIDINT; if(!(val & NEWLINE)) { if(val & SPACE) continue; /*skip space*/ if(val & STEQUAL) continue; /*skip '='*/ if(val & NUMBER) break; /*look for number*/ } TXTungetc(TXT); return INVALIDINT; /*not a number. abort*/ } name[0]=(char)c; for(n=1; n<256; n++ ) { if(TXTgetc(TXT,&c,&val)!=TRUE) break; if(val&NEWLINE) {TXTungetc(TXT);break;} if(val&SPACE)break; if(!(val&NUMBER)) ProgError("TR42", "%s(%ld): illegal char %s in number", fname (TXT->pathname), (long) TXT->Lines, quotechar (c)); if(n<8) name[n]=(char)c; } if(n<8)name[n]='\0'; name[8]='\0'; return (Int16)atoi(name); } /* read Blocks of the form ** [BLOCKID] ** identifier ... anything ... ** identifier ... anything ... */ static Bool TXTfindSection(struct TXTFILE *TXT,Bool Match) { Int16 c=0,val=0,n; char buffer[8]; while(1) { if(TXTskipComment(TXT)!=TRUE) return FALSE; if(TXTgetc(TXT,&c,&val)!=TRUE)return FALSE; if(c=='[') { for(n=0;n<256;n++) { if(TXTgetc(TXT,&c,&val)!=TRUE) return FALSE; if(c==']') { if(n<8)buffer[n]='\0'; if(Match==FALSE) return TRUE;/*any section is ok*/ Normalise(buffer,buffer); /*the right section?*/ if(strncmp(buffer,TXT->Section,8)==0) return TRUE; break; /*not the right section*/ } if(!(val & (NAME|NUMBER))) break; /*not a section*/ if(n<8) buffer[n]=c; } } while(1) /*look for end of line*/ { if(TXTgetc(TXT,&c,&val)!=TRUE)return FALSE; if(val & NEWLINE) break; } } } /* ** find the section boundaries, from current position in file */ static Bool TXTboundSection(struct TXTFILE *TXT) { Int16 c=0,val=0; if(TXTfindSection(TXT,TRUE)!=TRUE) return FALSE; TXT->SectionStart=TXT->Lines+1; /*check that we don't read twice the same section*/ if(TXT->SectionEnd>TXT->SectionStart) Bug("TR51", "TxtBdS"); if(TXTfindSection(TXT,FALSE)==TRUE) TXT->SectionEnd=TXT->Lines-1; else TXT->SectionEnd=TXT->Lines; /* set pointer to first section line*/ fseek(TXT->fp,0,SEEK_SET); TXT->Lines =1;/*start in line 1*/ while(TXT->LinesSectionStart) { if(TXTgetc(TXT,&c,&val)!=TRUE)return FALSE; } return TRUE; } Bool TXTseekSection(struct TXTFILE *TXT,const char *section) { if(TXTok!=TRUE) Bug("TR61", "TxtSks"); /*seek begin of file*/ TXT->SectionStart=0; TXT->SectionEnd =0; Normalise(TXT->Section,section); fseek(TXT->fp,0L,SEEK_SET); TXT->Lines =1;/*start in line 1*/ /*skipping comments, look for a line with [section]*/ return TXTboundSection(TXT); } /*read a texture definition*/ /*return FALSE if read End*/ Bool TXTreadTexDef(struct TXTFILE *TXT,char name[8],Int16 *szx,Int16 *szy) { if(TXTok!=TRUE) Bug("TR71", "TxtTxd"); if(TXTskipComment(TXT)==FALSE) return FALSE; /*End*/ if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) ProgError("TR73", "%s(%ld): expecting identifier", fname (TXT->pathname), (long) TXT->Lines); Normalise(name,name); *szx=TXTreadShort(TXT); *szy=TXTreadShort(TXT); return TRUE; } /*read a patch def. Return FALSE if could not find '*' */ Bool TXTreadPatchDef(struct TXTFILE *TXT,char name[8],Int16 *ofsx,Int16 *ofsy) { if(TXTok!=TRUE) Bug("TR81", "TxtRpd"); if(TXTskipComment(TXT)==FALSE) return FALSE; if(TXTcheckStartPatch(TXT)!=TRUE) return FALSE; /*not a patch line*/ if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) ProgError("TR83", "%s(%ld): expecting identifier", fname (TXT->pathname), (long) TXT->Lines); Normalise(name,name); *ofsx=TXTreadShort(TXT); *ofsy=TXTreadShort(TXT); return TRUE; } /* **TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE) */ Bool TXTentryParse(char *name,char *filenam,Int16 *x,Int16 *y,Bool *repeat, struct TXTFILE *TXT, Bool XY) { Int16 c=0,val=0; Bool comment; Int16 xx=INVALIDINT,yy=INVALIDINT; if(TXTreadIdent(TXT,name)!=TRUE) return FALSE; /* skip the equal*/ if(TXTgetc(TXT,&c,&val)!=TRUE) return FALSE; if(c!='=') TXTungetc(TXT); /* read integer*/ if(XY==TRUE) { xx=TXTreadOptionalShort(TXT); yy=TXTreadOptionalShort(TXT); } Normalise(filenam,name); TXTreadOptionalName(TXT,filenam); if(XY==TRUE) { if(xx==INVALIDINT) xx=TXTreadOptionalShort(TXT); if(yy==INVALIDINT) yy=TXTreadOptionalShort(TXT); } *repeat= TXTreadOptionalRepeat(TXT); *x=xx; *y=yy; for(comment=FALSE;;) { if(TXTgetc(TXT,&c,&val)!=TRUE)break; if(val & NEWLINE) break; if(val & COMMENT) /*eat commentaries*/ { comment=TRUE; continue;} if(val & SPACE) /*eat space*/ { continue;} if(comment==FALSE) ProgError("TR87", "%s(%ld): bad entry format", fname (TXT->pathname), (long) TXT->Lines); } return TRUE; } /* ** For any Writing of text files */ struct TXTFILE *TXTopenW(const char *file) /*open, and init if needed*/ { struct TXTFILE *TXT; size_t pathname_len; /*characters*/ if(TXTok!=TRUE) TXTinit(); pathname_len = strlen (file); TXT = (struct TXTFILE *)Malloc(sizeof(struct TXTFILE) + pathname_len); /*some inits */ strcpy (TXT->pathname, file); TXT->Lines =1;/*start in line 1*/ TXT->SectionStart=0; TXT->SectionEnd =0; TXT->fp = fopen(file,FOPEN_RT); if(TXT->fp==NULL) { TXT->fp = fopen(file,FOPEN_WT); } else { fclose(TXT->fp); TXT->fp = fopen(file,FOPEN_AT); Warning("TW03", "%s: already exists, appending to it", fname (file)); } if(TXT->fp==NULL) ProgError("TW05", "%s: %s", fname (file), strerror (errno)); return TXT; } void TXTcloseW(struct TXTFILE *TXT) { if (TXT == &TXTdummy) return; if(TXTok!=TRUE) Bug("TW91", "TxtClo"); fclose(TXT->fp); Free(TXT); } /* ** To write entries */ void TXTaddSection(struct TXTFILE *TXT,const char *def) { if (TXT == &TXTdummy) return; if(TXTok!=TRUE) Bug("TW11", "TxtAdS"); fprintf(TXT->fp,"[%.8s]\n",def); } void TXTaddEntry(struct TXTFILE *TXT,const char *name,const char *filenam,Int16 x,Int16 y,Bool repeat, Bool XY) { if (TXT == &TXTdummy) return; if(TXTok!=TRUE) Bug("TW21", "TxtAdE"); fprintf(TXT->fp,"%.8s",name); /* fprintf(TXT->fp,"%.8s=",name);*/ if(filenam!=NULL) fprintf(TXT->fp,"\t%.8s",filenam); if(XY==TRUE) fprintf(TXT->fp,"\t%d\t%d",x,y); if(repeat==TRUE) fprintf(TXT->fp,"\t*"); fprintf(TXT->fp,"\n"); } void TXTaddComment(struct TXTFILE *TXT,const char *text) { if (TXT == &TXTdummy) return; if(TXTok!=TRUE) Bug("TW31", "TxtAdC"); fprintf(TXT->fp,"# %.256s\n",text); } void TXTaddEmptyLine (struct TXTFILE *TXT) { if (TXT == &TXTdummy) return; if (TXTok != TRUE) Bug ("TW41", "TxtAdL"); putc ('\n', TXT->fp); } #endif /*DeuTex*/ deutex-4.4.902/src/texture.c0000644000324500032450000005207510305365544015241 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include "tools.h" #include "endianm.h" #include "text.h" #include "mkwad.h" #include "texture.h" #include "wadio.h" /* The wad format limits the maximum number of patches per texture. */ #define MAX_PATCHES 32767 /* add new patchs by cluster of 64 */ #define NEWPATCHS 0x40 /* add new textures by cluster of 64 */ #define NEWTEXTURES 0x40 /* more than 8000 textures is unreasonable */ #define MAXTEXTURES 0x2000 /* add new patch defs by cluster of 128*/ #define NEWPATCHESDEF 0x80 /* TEXU module that stores the textures definitions PNM modules that stores the patch names */ /***************Begin PNAME module*****************/ static struct PNMP{char name[8];} *PNMpatchs; static Int16 PNMtop; static Int16 PNMmax; static Int16 PNMknown; static Bool PNMok = FALSE; void PNMinit(char *buffer,Int32 size) { Int16 n,i; char picname[8]; Int32 pnames; /*find the number of entries in PNAME*/ pnames=0; if(size>4L) { pnames = peek_i32_le (buffer); if(pnames>0x7FFFL) ProgError("PA01", "Too many patches"); if(size<(4L+8L*pnames)) ProgError("PA02", "PNAMES has wrong size"); } /*initialise*/ PNMmax=(Int16)(pnames+NEWPATCHS); PNMpatchs=(struct PNMP *)Malloc(PNMmax*sizeof(struct PNMP)); PNMtop=(Int16)pnames; PNMknown=0; /*Read patches*/ if(pnames<=0)return; for(n=0;n=PNMmax) { PNMmax+=NEWPATCHS; PNMpatchs=(struct PNMP *)Realloc(PNMpatchs,PNMmax*sizeof(struct PNMP)); } } return idx; } /* ** get name from index */ void PNMgetPatchName(char name[8],Int16 index) { if(PNMok!=TRUE)Bug("PA91", "PNMok"); if(index>=PNMtop) Bug("PA92", "PnmGP>"); Normalise(name,PNMpatchs[index].name); } /* ** Insert in directory all the entries which are not ** referenced in DOOM.WAD */ Int16 PNMgetNbOfPatch(void) { return PNMtop; } Bool PNMisNew(Int16 idx) { if(PNMok!=TRUE)Bug("PA93", "PNMok"); if(idx>=PNMtop)Bug("PA94", "PnmIN>"); /*check if patch was added after initial definition*/ if(idx>=PNMknown) return TRUE; return FALSE; } void PNMfree(void) { PNMok=FALSE; Free(PNMpatchs); } /********Write PNAME entry in WAD********/ Int32 PNMwritePNAMEtoWAD(struct WADINFO *info) { Int16 idx; Int32 size =0; char buffer[8]; if(PNMok!=TRUE)Bug("PA95", "PNMok"); /*Write the Number of entries*/ size+=WADRwriteLong(info,PNMtop); /*Then write the names , '\0' padded*/ for(idx=0;idx=TXUtexMax) { TXUtexMax+=NEWTEXTURES; TXUtex=(struct TEXTUR *)Realloc(TXUtex,TXUtexMax*sizeof(struct TEXTUR)); } Normalise(TXUtex[TXUtexCur].Name,name); /*declare texture*/ TXUtex[TXUtexCur].szX=X; TXUtex[TXUtexCur].szY=Y; TXUtex[TXUtexCur].Npatches=0; /*check if we redefine other textures, and overide them.*/ for(t=0;t=TXUpatMax) { TXUpatMax+=NEWPATCHESDEF; TXUpat=(struct PATCH *) Realloc(TXUpat,TXUpatMax*sizeof(struct PATCH)); } if(TXUtexCur<0) Bug("TX92", "TXUTxC"); PNMgetPatchName(pname,pindex); /*check if index correct*/ TXUtex[TXUtexCur].Npatches+=1; /*increase texture's patch counter*/ TXUpat[TXUpatTop].Pindex=pindex;/*declare patch*/ TXUpat[TXUpatTop].ofsX=ofsX; TXUpat[TXUpatTop].ofsY=ofsY; TXUpatTop+=1; } void TXUfree(void) { if(TXUok!=TRUE) Bug("TX93", "TXUok"); Free(TXUpat); Free(TXUtex); TXUok=FALSE; } Bool TXUexist(char *Name) { int t; if(TXUok!=TRUE) Bug("TX94", "TXUok"); for(t=0;t=NbOfTex)Bug("TX97", "TxuRT"); WADRsetLong(info,ofsTble+tt*4,size); tt++; /*write the begining of texture definition*/ fseek (info->fd, info->wposit, SEEK_SET); /* Ugly */ if (output_texture_format != TF_NAMELESS) wad_write_name (info->fd, TXUtex[t].Name); size += 8; wad_write_i16 (info->fd, 0); size += 2; wad_write_i16 (info->fd, 0); size += 2; wad_write_i16 (info->fd, TXUtex[t].szX); size += 2; wad_write_i16 (info->fd, TXUtex[t].szY); size += 2; if (output_texture_format != TF_STRIFE11) { wad_write_i16 (info->fd, 0); size += 2; wad_write_i16 (info->fd, 0); size += 2; } wad_write_i16 (info->fd, TXUtex[t].Npatches); size += 2; for(p=0; p<(TXUtex[t].Npatches); p++) { if(pat+p>=TXUpatTop) Bug("TX98", "TxuP>D");/*number of patches exceeds definitions*/ wad_write_i16 (info->fd, TXUpat[pat+p].ofsX); size += 2; wad_write_i16 (info->fd, TXUpat[pat+p].ofsY); size += 2; wad_write_i16 (info->fd, TXUpat[pat+p].Pindex); size += 2; if (output_texture_format != TF_STRIFE11) { wad_write_i16 (info->fd, 0); size += 2; wad_write_i16 (info->fd, 0); size += 2; } } info->wposit = ftell (info->fd); /* Ugly */ } pat+=TXUtex[t].Npatches; } return size; } /* ** ** convert raw data (as read from wad) into Textures ** Data= texture entry ** if PatchSz>0, Patch defines the patch list */ void TXUreadTEXTURE( const char *texture1_name, const char *Data, Int32 DataSz, const char *Patch, Int32 PatchSz, Bool Redefn ) { Int32 Pos, Numtex, Numpat, dummy; /* texture data*/ Int16 t,p,i, Xsize, Ysize; /* size x and y */ /* nb of patches used to build it */ /* patch inside a texture */ Int16 Xofs, Yofs,Pindex; /* x,y coordinate in texture space*/ /* patch name index in PNAMES table */ Int32 MaxPindex; static char tname[8]; /*texture name*/ static char pname[8]; /*patch name*/ size_t header_size = 0; size_t item_size = 0; int have_texture_name = 0; int have_header_dummies = 0; if (input_texture_format == TF_NAMELESS) { header_size = 14; item_size = 10; have_texture_name = 0; have_header_dummies = 1; } else if (input_texture_format == TF_NONE) { Warning ("TX11", "No texture definitions to read"); return; /* FIXME is it OK to do that ? */ } else if (input_texture_format == TF_NORMAL) { header_size = 22; item_size = 10; have_texture_name = 1; have_header_dummies = 1; } else if (input_texture_format == TF_STRIFE11) { header_size = 18; item_size = 6; have_texture_name = 1; have_header_dummies = 0; } else { Bug ("TX99", "invalid itf %d", (int) input_texture_format); return; } /*get number of patches*/ if(PatchSz>0) { MaxPindex = peek_i32_le (Patch); dummy=4L+(MaxPindex*8L); if(dummy>PatchSz) ProgError("PA03", "PNAMES is corrupt"); } else { MaxPindex = PNMgetNbOfPatch(); } if((MaxPindex<0)||(MaxPindex>0x7FFF)) ProgError("PA04", "PNAMES: invalid patch count %ld", (long) MaxPindex); /*get number of textures*/ Numtex = peek_i32_le (Data); if(Numtex<0) ProgError("TX12", "%s: invalid texture count %ld", lump_name (texture1_name), (long) Numtex); if(Numtex>MAXTEXTURES) ProgError("TX13", "%s: too many textures (%ld/%ld)", lump_name (texture1_name), (long) Numtex, (long) MAXTEXTURES); /*read textures*/ for (t = 0; t DataSz) ProgError("TX14", "%s: unexpected EOL in entry %d", lump_name (texture1_name), (long) t); if (have_texture_name) { Normalise (tname, Data + Pos); Pos += 8; } else /* No name. Make one up (TEXnnnn)*/ { if (t > 9999) { Warning ("TX15", "%s: more than 10000 textures, ignoring excess", lump_name (texture1_name)); break; } sprintf (tname, "TEX%04d", (int) t); } Pos += 4; /* Skip 2 dummy unused fields */ Xsize = peek_i16_le (Data + Pos); Pos += 2; if((Xsize<0)||(Xsize>4096)) ProgError ("TX16", "%s: Texture %s: width out of bounds (%d)", lump_name (texture1_name), lump_name (tname), (int) Xsize); Ysize = peek_i16_le (Data + Pos); Pos += 2; if((Ysize<0)||(Ysize>4096)) ProgError ("TX17", "%s: Texture %s: height out of bounds (%d)", lump_name (texture1_name), lump_name (tname), (int) Ysize); if (have_header_dummies) Pos += 4; /* Skip 2 dummy unused fields */ Numpat = peek_i16_le (Data + Pos)&0xFFFF; Pos += 2; if(Numpat<0) { nf_err("TX18", "%s: Texture %s: negative patch count %d, skipping texture", lump_name (texture1_name), lump_name (tname), (int) Numpat); continue; } /* declare texture */ TXUdefineCurTex(tname,Xsize,Ysize,Redefn); if (Pos + (long) Numpat * item_size > DataSz) ProgError("TX19", "%s(%ld): Texture %s: unexpected EOL", lump_name (texture1_name), (long) t, lump_name (tname)); for (p = 0; p < Numpat; p++, Pos += item_size) { Xofs = peek_i16_le (Data + Pos); if((Xofs<-4096)||(Xofs>4096)) ProgError("TX20", "%s(%ld): Texture %s(%d/%d): bad patch X-offset %d", lump_name (texture1_name), (long) t, lump_name (tname), (int) p, (int) Numpat, (int) Xofs); Yofs = peek_i16_le (Data + Pos + 2); if((Yofs<-4096)||(Yofs>4096)) ProgError("TX21", "%s(%ld): Texture %s(%d/%d): bad patch Y-offset %d", lump_name (texture1_name), (long) t, lump_name (tname), (int) p, (int) Numpat, (int) Yofs); Pindex = peek_i16_le (Data + Pos + 4); if((Pindex<0)||(Pindex>MaxPindex)) ProgError("TX22", "%s(%ld): Texture %s(%d/%d): bad patch index %d", lump_name (texture1_name), (long) t, lump_name (tname), (int) p, (int) Numpat, (int) Pindex); /*if new patch list, recalculate Pindex*/ if(PatchSz>0) { for(dummy=(4L+(Pindex*8L)),i=0;i<8;i++) pname[i]=Patch[dummy+i]; Pindex=PNMgetPatchIndex(pname); } /*declare patch*/ TXUaddPatchToCurTex(Pindex,Xofs,Yofs); } } } Bool TXUcheckTex(Int16 npatch,Int16 *PszX) { Int16 t,tt,p,pat,col,top,found; Int16 bit,C,b; /*bit test*/ Int16 Meduza; Bool Res=TRUE; if(TXUok!=TRUE) Bug("TX23", "TXUok"); Output("Checking textures\n"); if(TXUtexTop<1) Bug("TX24", "TxuNTx"); /* FIXME assign a code to this message */ if(TXUtexTop<100) Output("Warning: Some textures could be missing! (less than 100 defined)\n"); for(pat=0, t=0; tTXUpatTop) Bug("TX25", "TxuP>D"); /* ** check width */ for(bit=1,C=0,b=0;b<16;b++,bit<<=1) if((TXUtex[t].szX)&bit) C++; if(C>1) { Output("Warning: Width of %s is not a power of 2\n", lump_name (TXUtex[t].Name)); /* FIXME assign a code to this message */ Res=FALSE; } /* ** check height */ if(TXUtex[t].szY>128) { Output("Warning: Height of %s is more than 128\n", lump_name (TXUtex[t].Name)); /* FIXME assign a code to this message */ Res=FALSE; } /* ** check patch for: ** - void columns (crashes the game at boot) ** - possible meduza effect (if the patch is used on 2S walls) */ Meduza=0; for(col=0;col=npatch) Bug("TX26", "~TxuP>D"); if(col>=TXUpat[pat+p].ofsX) { top=PszX[TXUpat[pat+p].Pindex]+TXUpat[pat+p].ofsX; if(col=2) break; /*two patches on same column. Meduza effect*/ else Meduza++; /*keep looking for patches*/ } } } if(found==FALSE) { /* FIXME assign a code to this message */ Output("Warning: Empty column %d in texture %s\n", col, lump_name (TXUtex[t].Name)); Res=FALSE; } } if(Meduza>=2) /*there is a colum with two patches*/ { /* FIXME assign a code to this message */ Output("Warning: Texture %s should not be used on a two sided wall.\n", lump_name (TXUtex[t].Name)); } pat+=TXUtex[t].Npatches; } /* ** check duplication */ for(t=0; t=TXUtexMax) { TXUtexMax+=NEWTEXTURES; TXUtex=(struct TEXTUR *)Realloc(TXUtex,TXUtexMax*sizeof(struct TEXTUR)); } Normalise(TXUtex[TXUtexCur].Name,Name); /*declare texture*/ TXUtex[TXUtexCur].szX=0; TXUtex[TXUtexCur].szY=0; TXUtex[TXUtexCur].Npatches=0; } /* ** list the names of the textures defined */ void TXUlistTex(void) { Int16 t; if(TXUok!=TRUE) Bug("TX28", "TXUok"); for (t= 0; t =TXUpatTop) Bug("TX32", "TxuP>D"); PNMgetPatchName(pname,TXUpat[pat+p].Pindex); fprintf(out,"*\t%-8.8s ",pname); fprintf(out,"\t%d\t%d\n",TXUpat[pat+p].ofsX,TXUpat[pat+p].ofsY); } } pat+=TXUtex[t].Npatches; } fprintf(out,";End\n"); if (fclose(out) != 0) ProgError("TX33", "%s: %s", file, strerror(errno)); } /* ** read texture as text file ** */ void TXUreadTexFile(const char *file,Bool Redefn) { Int16 Pindex; Int16 xsize=0,ysize=0,ofsx=0,ofsy=0; char tname[8]; char pname[8]; Int16 t,bit,C,b; /*to check Xsize*/ struct TXTFILE *TXT; TXT=TXTopenR(file, 0); /* if(TXTbeginBloc(TXT,"TEXTURES")!=TRUE)ProgError("TX34", "Invalid texture file format: %s",file); */ for(t=0;t4096) Warning("TX36", "Texture %s: width %d > 4096, XDoom 20001001 may crash", lump_name (tname), (int) xsize); if (xsize>512) Warning("TX37", "Texture %s: width %d > 512, Doom may freeze", lump_name (tname), (int) xsize); for(bit=1,C=0,b=0;b<16;b++,bit<<=1) if(xsize&bit) C++; if(C>1) Warning("TX38", "Texture %s: width %d not a power of 2", lump_name (tname), (int) xsize); /* check Y size */ if(ysize<0) ProgError("TX39", "Texture %s: height %d < 0", lump_name (tname), (int) ysize); if(ysize>128) Warning("TX40", "Texture %s: height %d > 128, won't be rendered properly", lump_name (tname), (int) ysize); /* declare texture */ TXUdefineCurTex(tname,xsize,ysize, Redefn); { long npat = 0; while (TXTreadPatchDef(TXT,pname,&ofsx,&ofsy) == TRUE) { if (npat == MAX_PATCHES) Warning("TX42", "Texture %s: more than 32767 patches, ignoring excess", lump_name (tname), ofsx); else if (npat > MAX_PATCHES) ; /* Silently drop the rest */ else { /* declare a patch wall, getting index or declaring a new index */ Pindex=PNMgetPatchIndex(pname); TXUaddPatchToCurTex(Pindex,ofsx,ofsy); } if (npat <= MAX_PATCHES) npat++; } } } Phase("TX44", "Read %d textures from %s", t, file); TXTcloseR(TXT); } /***************End TEXTURE module*********************/ #endif /*DeuTex*/ deutex-4.4.902/src/tools.c0000644000324500032450000004352010305114675014671 0ustar aymaym00000000000000/* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* ** This code should contain all the tricky O/S related ** functions. If you're porting DeuTex/DeuSF, look here! */ #include "deutex.h" #include #include #include "tools.h" #include "log.h" /*MSDOS*/ #if DT_OS == 'd' # define SEPARATOR "\\" # if DT_CC == 'd' /* DJGPP for DOS */ # include # include # include # include # include # elif DT_CC == 'b' /* Borland C for DOS */ # include # include # include # else /* Other compiler (MSC ?) for DOS */ # include # include # include # endif /*OS/2*/ #elif DT_OS == 'o' # define SEPARATOR "\\" # include # include # include /*UNIX*/ #else # define SEPARATOR "/" # include # include # include #endif #if DT_OS == 'o' && DT_CC == 'i'\ || DT_OS == 'd' && DT_CC == 'm' # include #else # include #endif #include #include #include #include #include static const char hex_digit[16] = "0123456789ABCDEF"; /* * check_types * Sanity checks on the specified-width types. * Will help catching porting errors. */ typedef struct { const char *name; size_t mandated_size; size_t actual_size; } type_check_t; static const type_check_t type_checks[] = { { "Int8", 1, sizeof (Int8) }, { "Int16", 2, sizeof (Int16) }, { "Int32", 4, sizeof (Int32) }, { "UInt8", 1, sizeof (UInt8) }, { "UInt16", 2, sizeof (UInt16) }, { "UInt32", 4, sizeof (UInt32) } }; void check_types (void) { const type_check_t *t; for (t = type_checks; t - type_checks < sizeof type_checks / sizeof *t; t++) { /* FIXME Perhaps too strict. Wouldn't "<" suffice ? */ if (t->actual_size != t->mandated_size) ProgError ("AA01", "Type %s has size %d (should be %d);" " fix deutex.h and recompile", t->name, (int) t->actual_size, (int) t->mandated_size); } } /* ** Resize a file ** returns 0 if okay -1 if failed. */ Int16 Chsize(int handle,Int32 newsize) { #if DT_OS == 'd' # if DT_CC == 'd' return (Int16)ftruncate(handle, newsize); # elif DT_CC == 'b' || DT_CC == 'm' return (Int16)chsize(handle,newsize); # else # error Chsize unimplemented # endif #elif DT_OS == 'o' # if DT_CC == 'b' return (Int16)chsize(handle,newsize); # else return (Int16)_chsize(handle,newsize); # endif #else return (Int16)ftruncate(handle, newsize); #endif } /* ** Delete a file */ void Unlink(const char *file) { remove (file); } /* ** Get a file time stamp. (date of last modification) */ Int32 GetFileTime(const char *path) { Int32 time; struct stat statbuf; stat(path,&statbuf); time =statbuf.st_ctime; return time; } /* ** Set a file time stamp. */ void SetFileTime(const char *path, Int32 time) { struct utimbuf stime; stime.modtime=stime.actime=time; #if DT_OS == 'o' && DT_CC != 'b' _utime(path, &stime); #else utime(path, &stime); #endif } /* ** Copy memory */ void Memcpy(void *dest,const void *src, long n) { if(n<0) Bug("MM21", "MovInf"); /*move inf to zero*/ if(n==0)return; #if DT_OS == 'd' # if DT_CC == 'd' memcpy((char *)dest,(char *)src,(size_t)n); # else if(n>0x10000L) Bug("MM22", "MovSup"); /*DOS limit: not more than 0x10000*/ _fmemcpy(dest,src,(size_t)n); # endif #elif DT_OS == 'o' memcpy((char *)dest,(char *)src,(size_t)n); #else memcpy((char *)dest,(char *)src,(size_t)n); #endif } /* ** Set memory */ void Memset(void *dest,char car, long n) { if(n<0) Bug("MM11", "MStInf"); /*set inf to zero*/ if(n==0)return; #if DT_OS == 'd' # if DT_CC == 'd' memset(dest,car,(size_t)n); # else if(n>0x10000L) Bug("MM12", "MStSup"); /*DOS limit: not more than 0x10000*/ _fmemset(dest,car,(size_t)n); # endif #elif DT_OS == 'o' memset(dest,car,(size_t)n); #else memset(dest,car,(size_t)n); #endif } /* ** Allocate memory */ /*code derived from DEU*/ #define SIZE_THRESHOLD 0x400L #define SIZE_OF_BLOCK 0xFFFL /* actually, this is (size - 1) */ void *Malloc (long size) { void *ret; if(size<1) { Warning("MM02", "Attempt to allocate %ld bytes",size); size=1; } #if DT_OS == 'd' && DT_CC == 'b' ret = farmalloc( size); #else if ((size_t) size != size) ProgError ("MM03", "Tried to allocate %ld b but couldn't; use another compiler", size); ret = malloc((size_t) size); #endif if (ret==NULL) ProgError("MM04", "Out of memory (needed %ld bytes)", size); return ret; } /* ** Reallocate memory */ void *Realloc (void *old, long size) { void *ret; if(size<1) { Warning("MM05", "Attempt to allocate %ld bytes",size); size=1; } #if DT_OS == 'd' && DT_CC == 'b' ret = farrealloc( old, size); #else if ((size_t) size != size) ProgError ("MM06", "Tried to realloc %ld b but couldn't; use another compiler", size); ret = realloc( old, (size_t)size); #endif if (ret==NULL) ProgError("MM07", "Out of memory (needed %ld bytes)", size); return ret; } /* ** Free */ void Free( void *ptr) { #if DT_OS == 'd' && DT_CC == 'b' farfree (ptr); #else free (ptr); #endif } /*****************************************************/ /* ** Use only lower case file names */ void ToLowerCase(char *file) { Int16 i; for(i=0;(i<128)&&(file[i]!='\0');i++) file[i]=tolower((((Int16)file[i])&0xFF)); } static void NameDir(char file[128], const char *path, const char *dir, const char *sdir) { file[0]='.'; file[1]='\0'; if(path!=NULL) if(strlen(path)>0){ strncpy(file,path,80);} if(dir!=NULL) if(strlen(dir)>0) { strcat(file,SEPARATOR);strncat(file,dir,12);} if(sdir!=NULL) if(strlen(sdir)>0) { strcat(file,SEPARATOR);strncat(file,sdir,12);} ToLowerCase(file); } /* ** Create directory if it does not exists */ void MakeDir(char file[128], const char *path, const char *dir, const char *sdir) { NameDir(file,path,dir,sdir); #if DT_OS == 'd' # if DT_CC == 'd' mkdir(file,0); /*2nd argument not used in DOS*/ # elif DT_CC == 'b' || DT_CC == 'm' mkdir(file); # else # error MakeDir unimplemented # endif #elif DT_OS == 'o' # if DT_CC == 'b' mkdir(file); # else _mkdir(file); # endif #else mkdir(file,(mode_t)S_IRWXU); /*read write exec owner*/ #endif } /* ** Create a file name, by concatenation ** returns TRUE if file exists FALSE otherwise */ Bool MakeFileName(char file[128], const char *path, const char *dir, const char *sdir, const char *name, const char *extens) { FILE *fp; char name2[8]; /* AYM 1999-01-13: keep checker happy */ /* deal with VILE strange name ** replace the VILE[ VILE\ VILE] ** by VIL@A VIL@B VIL@C */ Normalise(name2,name); /* FIXME AYM 1999-06-09: Not sure whether it is a good thing to keep this translation scheme for the Unix version. However, removing it would make the DOS version and the Unix version incompatible. */ switch(name2[4]) { case '[': name2[4]='$';break; case '\\': name2[4]='@';break; case ']': name2[4]='#';break; } switch(name2[6]) { case '[': name2[6]='$';break; case '\\': name2[6]='@';break; case ']': name2[6]='#';break; } NameDir(file,path,dir,sdir); /* ** file name */ strcat(file,SEPARATOR); strncat(file,name2,8); strcat(file,"."); strncat(file,extens,4); ToLowerCase(file); /* ** check if file exists */ fp=fopen(file,FOPEN_RB); if(fp!=NULL) { fclose(fp); /* AYM 1999-01-??: fclose() used to be called even if fopen() had returned NULL! It gave beautiful segfaults. */ return TRUE; } return FALSE; } /* ** Get the root name of a WAD file */ void GetNameOfWAD(char name[8], const char *path) { Int16 n, nam,len; len=(Int16)strlen(path); /*find end of DOS or Unix path*/ for(nam=n=0;n> 4; *p++ = *name & 0x0f; } } *p = '\0'; } return buf; } /* * short_dump - return string containing hex dump of buffer * * Not reentrant (returns pointer on static buffer). Length * is silently limited to 16 bytes. */ char *short_dump (const char *data, size_t size) { #define MAX_BYTES 16 static char buf[3 * MAX_BYTES]; char *b = buf; size_t n; for (n = 0; n < size && n < MAX_BYTES; n++) { if (n > 0) *b++ = ' '; *b++ = hex_digit[((unsigned char) data[n]) >> 4]; *b++ = hex_digit[((unsigned char) data[n]) & 0x0f]; } *b++ = '\0'; return buf; } /* * quotechar - return the safe representation of a char * * Not reentrant (returns pointer on static buffer). The string is * guaranteed to be exactly three characters long and not contain * any control or non-ASCII characters. */ const char *quotechar (char c) { static char buf[4]; if (c >= 32 && c <= 126) { buf[0] = '"'; buf[1] = c; buf[2] = '"'; buf[3] = '\0'; } else { buf[0] = hex_digit[((unsigned char) c) >> 4]; buf[1] = hex_digit[((unsigned char) c) & 0x0f]; buf[2] = 'h'; buf[3] = '\0'; } return buf; } /* ** Output and Error handling */ static Bool asFile=FALSE; static Int16 Verbosity=2; static FILE *Stdout; /*command output*/ static FILE *Stderr; /*errors*/ static FILE *Stdwarn; /*warningss*/ static FILE *Stdinfo; /*infos*/ #define stderr_ (Stderr != NULL ? Stderr : stderr) #define stdinfo_ (Stdinfo != NULL ? Stdinfo : stdout) #define stdout_ (Stdout != NULL ? Stdout : stdout) #define stdwarn_ (Stdwarn != NULL ? Stdwarn : stderr) void PrintInit(Bool asfile) { #if DT_OS == 'o' setbuf(stdout,(char *)NULL); #endif /*clear a previous call*/ PrintExit(); /* choose */ if(asfile==TRUE) { if((Stdout=fopen("output.txt",FOPEN_WT))==NULL) ProgError ("DI10", "output.txt: %s", strerror (errno)); if((Stderr=fopen("error.txt",FOPEN_WT))==NULL) { Stderr=stderr; ProgError ("DI20", "error.txt: %s", strerror (errno)); } Stdinfo=stdout; Stdwarn=Stderr; } else { Stdout=stdout; Stderr=stderr; Stdwarn=stderr; Stdinfo=stdout; } asFile=asfile; } void PrintVerbosity(Int16 level) { Verbosity=(level<0)? 0: (level>4)? 4:level; } void PrintExit(void) { if(asFile==TRUE) { fclose(Stdout); fclose(Stderr); /*fclose(Stdinfo);*/ } } void ActionDummy(void) { return; } static void (*Action)(void)=ActionDummy; void ProgErrorCancel(void) { Action = ActionDummy; } void ProgErrorAction(void (*action)(void)) { Action = action; } void ProgError (const char *code, const char *fmt, ...) { va_list args; fflush (stdout_); fprintf(stderr_, "E %s ", code); lprintf("E %s ", code); va_start(args, fmt); vfprintf(stderr_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc('\n', stderr_); lputc('\n'); (*Action)(); /* execute error handler*/ PrintExit(); exit(2); } /* * nf_err - non fatal error message */ void nf_err (const char *code, const char *fmt, ...) { va_list args; fflush(stdout_); fprintf(stderr_, "%c %s ", MSGCLASS_ERR, code); lprintf("%c %s ", MSGCLASS_ERR, code); va_start(args, fmt); vfprintf(stderr_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc('\n', stderr_); lputc('\n'); fflush(stderr_); } void Bug (const char *code, const char *fmt, ...) { va_list args; fflush(stdout_); fprintf(stdwarn_, "%c %s ", MSGCLASS_BUG, code); lprintf("%c %s ", MSGCLASS_BUG, code); va_start(args, fmt); vfprintf(stderr_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc('\n', stderr_); lputc('\n'); fputs("Please report that bug\n", stderr_); lputs("Please report that bug\n"); /* CloseWadFiles();*/ PrintExit(); exit(3); } void Warning (const char *code, const char *fmt, ...) { va_list args; fflush(stdout_); fprintf(stdwarn_, "%c %s ", MSGCLASS_WARN, code); lprintf("%c %s ", MSGCLASS_WARN, code); va_start(args, fmt); vfprintf(stdwarn_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc('\n', stdwarn_); lputc('\n'); } void LimitedWarn (int *left, const char *code, const char *fmt, ...) { if (left == NULL || (left != NULL && *left > 0)) { va_list args; fflush(stdout_); fprintf(stdwarn_, "%c %s ", MSGCLASS_WARN, code); lprintf("%c %s ", MSGCLASS_WARN, code); va_start(args, fmt); vfprintf(stdwarn_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc('\n', stdwarn_); lputc('\n'); } if (left != NULL) (*left)--; } void LimitedEpilog (int *left, const char *code, const char *fmt, ...) { if (left != NULL && *left < 0) { fflush (stdout_); if (fmt != NULL) { va_list args; fprintf(stdwarn_, "%c %s ", MSGCLASS_WARN, code); lprintf("%c %s ", MSGCLASS_WARN, code); va_start (args, fmt); vfprintf (stdwarn_, fmt, args); va_end (args); va_start (args, fmt); vlprintf (fmt, args); va_end (args); } fprintf (stdwarn_, "%d warnings omitted\n", - *left); lprintf ("%d warnings omitted\n", - *left); } } void Output (const char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stdout_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); } void Info (const char *code, const char *fmt, ...) { if (Verbosity >= 1) { va_list args; fprintf(stdinfo_, "%c %s ", MSGCLASS_INFO, code); lprintf("%c %s ", MSGCLASS_INFO, code); va_start(args, fmt); vfprintf(stdinfo_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc('\n', stdinfo_); lputc('\n'); } } void Phase (const char *code, const char *fmt, ...) { if (Verbosity >= 2) { va_list args; fprintf(stdinfo_, "%c %s ", MSGCLASS_INFO, code); lprintf("%c %s ", MSGCLASS_INFO, code); va_start(args, fmt); vfprintf(stdinfo_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc('\n', stdinfo_); lputc('\n'); } } void Detail (const char *code, const char *fmt, ...) { if (Verbosity >= 3) { va_list args; fprintf (stdinfo_, "%c %s ", MSGCLASS_INFO, code); lprintf ("%c %s ", MSGCLASS_INFO, code); va_start(args, fmt); vfprintf(stdinfo_, fmt, args); va_end(args); va_start(args, fmt); vlprintf(fmt, args); va_end(args); fputc ('\n', stdinfo_); lputc ('\n'); } } #if 0 Int16 NbP=0; void Progress(void) { NbP++; if(NbP&0xF==0) fprintf(stdinfo_,"."); if(NbP>0x400) { NbP=0; fprintf(stdinfo_,"\n"); } } void ProgressEnds(void) { fprintf(stdinfo_,"\n"); } #endif deutex-4.4.902/src/usedidx.c0000644000324500032450000000606410304423077015176 0ustar aymaym00000000000000/* * usedidx.c * Palette index usage statistics (cf -usedidx) */ /* This file is Copyright © 1994-1995 Olivier Montanuy, Copyright © 1999-2005 André Majorel. It may incorporate code derived from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include "tools.h" #include "usedidx.h" /* * usedidx_begin_lump * Call this before the first call to usedidx_count for * a given lump. */ void usedidx_begin_lump (cusage_t *cusage, const char *name) { int i; if (cusage == NULL) Bug ("UI10", "usedidx_begin_lump: null cusage"); cusage->lump_uses = Malloc (NCOLOURS * sizeof *cusage->lump_uses); for (i = 0; i < NCOLOURS; i++) cusage->lump_uses[i] = 0; memcpy (cusage->lump_name, name, sizeof cusage->lump_name); } /* * usedidx_pixel * Call this for each pixel for a given lump. */ void usedidx_pixel (cusage_t *cusage, unsigned char idx) { cusage->lump_uses[idx]++; } /* * usedidx_end_lump * Call this when you're done with a given lump. */ void usedidx_end_lump (cusage_t *cusage) { int i; if (cusage == NULL) Bug ("UI20", "usedidx_end_lump: null cusage"); for (i = 0; i < NCOLOURS; i++) { if (cusage->lump_uses[i] > 0) { if (cusage->uses[i] == 0) memcpy (cusage->where_first[i], cusage->lump_name, sizeof cusage->where_first[i]); cusage->uses[i] += cusage->lump_uses[i]; cusage->nlumps[i]++; } } Free (cusage->lump_uses); } /* * usedidx_rectangle * Call this to update the cusage_t structure for a whole * array of pixels at once. The array is supposed not to * contain transparent pixels so this is not for pictures; * it's for flats and rectangular graphic lumps (E.G. * 320x200 "TITLE" from Heretic or Hexen and 10x12 * "GNUM[0-9]" from Doom alpha.) */ void usedidx_rectangle (const char *buf, long buf_size, const char *name, cusage_t *cusage) { const unsigned char *p = (const unsigned char *) buf; const unsigned char *pmax = p + buf_size; unsigned long *uses = Malloc (NCOLOURS * sizeof *uses); int i; for (i = 0; i < NCOLOURS; i++) uses[i] = 0; for (; p < pmax; p++) uses[*p]++; for (i = 0; i < NCOLOURS; i++) { if (uses[i] > 0) { if (cusage->uses[i] == 0) memcpy (cusage->where_first[i], name, 8); cusage->uses[i] += uses[i]; cusage->nlumps[i]++; } } Free (uses); } deutex-4.4.902/src/version.c0000644000324500032450000000005110304153771015205 0ustar aymaym00000000000000const char deutex_version[] = "4.4.902"; deutex-4.4.902/src/wadio.c0000644000324500032450000000476510304423201014627 0ustar aymaym00000000000000/* * wadio.c * Wad low level I/O routines, without error checking. * AYM 1999-03-06 */ /* This file is copyright André Majorel 1999-2005. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "deutex.h" #include #include "endianio.h" #include "wadio.h" /* * wad_read_i16 * wad_read_i32 * wad_write_i16 * wad_write_i32 * * Read and write 16-bit and 32-bit signed integers, with * the defined endianness. By default, all wad I/O is done * in little-endian mode. * * Return 0 on success, non-zero on failure. */ int (* wad_write_i16) (FILE *, Int16) = fwrite_i16_le; int (* wad_write_i32) (FILE *, Int32) = fwrite_i32_le; int (* wad_read_i16) (FILE *, Int16 *) = fread_i16_le; int (* wad_read_i32) (FILE *, Int32 *) = fread_i32_le; /* * set_input_wad_endianness * set_output_wad_endianness * * Define the endianness to use for wad input and output * respectively. Normally, all wads are little-endian. */ void set_output_wad_endianness (int big_endian) { wad_write_i16 = big_endian ? fwrite_i16_be : fwrite_i16_le; wad_write_i32 = big_endian ? fwrite_i32_be : fwrite_i32_le; } void set_input_wad_endianness (int big_endian) { wad_read_i16 = big_endian ? fread_i16_be : fread_i16_le; wad_read_i32 = big_endian ? fread_i32_be : fread_i32_le; } /* * wad_read_name * wad_write_name * * Read and write a directory name to a wad. The name is * truncated to 8 characters, upper-cased, terminated and * padded to 8 with NULs. * * Return 0 on success, non-zero on failure. */ int wad_read_name (FILE *fd, char name[8]) { size_t n; int end = 0; for (n = 0; n < 8; n++) { int c = getc (fd); name[n] = end ? '\0' : toupper (c); if (c == '\0') end = 1; } return feof (fd) || ferror (fd); } int wad_write_name (FILE *fd, const char *name) { size_t n; for (n = 0; n < 8 && name[n]; n++) putc (toupper (name[n]), fd); for (; n < 8; n++) putc ('\0', fd); return ferror (fd); } deutex-4.4.902/VERSION0000644000324500032450000000001010304153704013624 0ustar aymaym000000000000004.4.902 deutex-4.4.902/Makefile.in0000644000324500032450000002254510305362240014640 0ustar aymaym00000000000000# Makefile of DeuTex/DeuSF # by Per Allansson, Olivier Montanuy and André Majorel # # Platform-specific notes: # # Unix User targets should work on all Unices. Some _developer_ # targets, however, require Elinks, GCC or GNU tar and gzip. # # DOS "make [all]" should work with DJGPP and Cygwin. With other # compilers, use the batch files in dos\ instead. # "make install" will most likely not work ; install the # executables by hand. # # Others Don't know. Send feedback to the maintainer. # # Compiled by developers DCFLAGS = -g -Wall -Wpointer-arith -Wstrict-prototypes -pg DCC = gcc DLDFLAGS = -g -pg #DEFINES = -DDT_ALPHA -DDT_PRIVATE #DEFINES = -DDT_PRIVATE ######### do not edit after this line ######### VERSION = `cat VERSION` DISTARC = deutex-$(VERSION).tar.gz DISTARCDOS = deutex-$(VERSION).zip DISTARCDOS8 = dtex`tr -cd '[0-9]' $@. && mv $@. $@ all: deutex deusf deutex: $(OBJTEX) tmp/_deutex $(CC) $(LDFLAGS) -o deutex $(OBJTEX) -lm deusf: $(OBJSF) tmp/_deusf $(CC) $(LDFLAGS) -o deusf $(OBJSF) -lm dall: ddeutex ddeusf ddt: ddeutex dds: ddeusf ddeutex: $(DOBJTEX) $(DCC) $(DLDFLAGS) -lm -o deutex $(DOBJTEX) @# Force next "make deutex" to relink (sleep 1; mkdir -p tmp; >tmp/_deutex) & ddeusf: $(DOBJSF) $(DCC) $(DLDFLAGS) -lm -o deusf $(DOBJSF) @# Force next "make deusf" to relink (sleep 1; mkdir -p tmp; >tmp/_deusf) & tmp/_deutex: [ -d tmp ] || mkdir tmp >$@ tmp/_deusf: [ -d tmp ] || mkdir tmp >$@ install: install -p -m 0755 deutex $(BINDIR) install -p -m 0755 deusf $(BINDIR) install -p -m 0644 deutex.6 $(MANDIR)/man6 if [ -d $(MANDIR)/man6/deusf.6 ]; then rmdir $(MANDIR)/man6/deusf.6; fi ln -sf deutex.6 $(MANDIR)/man6/deusf.6 src/version.c: VERSION printf "const char deutex_version[] = \"%s\";\n" $(VERSION) >$@ strip: deutex deusf strip deutex strip deusf msg: msgtex msgtex: $(MSGTEX) doc: $(DDOCUNIX) unixtmp1: mkdir -p $@ unixtmp1/CHANGES: docsrc/changes.html VERSION scripts/html2txt docsrc/changes.html >$@_ && mv $@_ $@ unixtmp1/COPYING: docsrc/COPYING cp -p docsrc/COPYING $@ unixtmp1/COPYING.LIB: docsrc/COPYING.LIB cp -p docsrc/COPYING.LIB $@ unixtmp1/FAQ: docsrc/faq.html VERSION echo 'THIS IS A GENERATED FILE -- DO NOT EDIT !' >$@.1 printf 'Edit docsrc/faq.html instead.\n\n' >>$@.1 links -dump docsrc/faq.html >>$@.1 sed 's/^ //; s/^ //' $@.1 >$@.2 rm -f $@.1 mv $@.2 $@ unixtmp1/INSTALL: docsrc/INSTALL VERSION scripts/process scripts/process docsrc/INSTALL >$@ unixtmp1/LICENCE: docsrc/LICENCE VERSION scripts/process scripts/process docsrc/LICENCE >$@ unixtmp1/README: docsrc/README VERSION scripts/process scripts/process docsrc/README >$@ unixtmp1/TODO: docsrc/todo.html VERSION echo 'THIS IS A GENERATED FILE -- DO NOT EDIT !' >$@.1 printf 'Edit docsrc/todo.html instead.\n\n' >>$@.1 links -dump docsrc/todo.html >>$@.1 sed 's/^ //' $@.1 >$@.2 rm -f $@.1 mv $@.2 $@ unixtmp1/deutex.6: docsrc/deutex.6 VERSION unixtmp1/deutex.6.opt\ unixtmp1/deutex.6.diag scripts/process scripts/process docsrc/deutex.6 >$@ unixtmp1/deutex.6.diag: echo 'FIXME \-\- not implemented yet' >$@ unixtmp1/deutex.6.opt: deutex ./deutex -man >$@ unixtmp1/dtexman6.txt: docsrc/dtexman6.txt cp -p docsrc/dtexman6.txt $@ dostmp1: mkdir -p $@ dostmp1/changes.txt: unixtmp1/CHANGES todos $@ touch -r unixtmp1/CHANGES $@ dostmp1/copying: unixtmp1/COPYING todos $@ touch -r unixtmp1/COPYING $@ dostmp1/copying.lib: unixtmp1/COPYING.LIB todos $@ touch -r unixtmp1/COPYING.LIB $@ dostmp1/dtexman6.txt: unixtmp1/dtexman6.txt todos $@ touch -r unixtmp1/dtexman6.txt $@ dostmp1/faq.txt: unixtmp1/FAQ todos $@ touch -r unixtmp1/FAQ $@ dostmp1/install.txt: docsrc/INSTALL VERSION scripts/process scripts/process docsrc/INSTALL | todos >$@ dostmp1/licence.txt: unixtmp1/LICENCE todos $@ touch -r unixtmp1/LICENCE $@ dostmp1/manpage.txt: unixtmp1/deutex.6 nroff -man -Tlatin1 unixtmp1/deutex.6 | ul -t dumb | todos >$@ touch -r unixtmp1/deutex.6 $@ dostmp1/readme.txt: docsrc/README VERSION scripts/process scripts/process docsrc/README | todos >$@ dostmp1/readme-bin.txt: docsrc/readme.dos VERSION scripts/process scripts/process docsrc/readme.dos | todos >$@ dostmp1/todo.txt: unixtmp1/TODO todos $@ touch -r unixtmp1/TODO $@ clean: rm -f $(OBJTEX) $(OBJSF) $(DOBJTEX) $(DOBJSF) deutex deusf rm -f deutex.exe deusf.exe # dist - make the distribution archive for Unix (.tar.gz) dist: $(DISTFILES) $(DDOCUNIX) mkdir -p $(DISTDIR) tar cf - $(DISTFILES) | (cd $(DISTDIR) && tar xvf -) cp -p $(DDOCUNIXFILES) $(DISTDIR) tar -zcf $(DISTARC) $(DISTDIR) rm -rf $(DISTDIR) # distdos - make the distribution archive DOS (.zip, 8+3) distdos: $(DISTFILES) $(DDOCDOS) mkdir -p $(DISTDIRDOS) tar cf - $(DISTFILES) | (cd $(DISTDIRDOS) && tar xvf -) cp -p $(DDOCDOSFILES) $(DISTDIRDOS) if [ -e $(DISTARCDOS) ]; then rm $(DISTARCDOS); fi zip -D -X -9 -r $(DISTARCDOS) $(DISTDIRDOS) rm -rf $(DISTDIRDOS) printf 'DeuTex %s\nhttp://www.teaser.fr/~amajorel/deutex/'\ "$(VERSION)" | zip -z $(DISTARCDOS) # distbindos - make the DOS binary distribution archive (.zip, 8+3) TMP=tmpd distbindos: $(DISTFILESBIN) $(DDOCDOS) dostmp1/readme-bin.txt mkdir -p $(TMP) cp -dpP $(DISTFILESBIN) $(TMP) cp -p $(DDOCDOSFILES) $(TMP) # Use a different readme.txt because this is a binary distribution cp -p dostmp1/readme-bin.txt $(TMP)/readme.txt # INSTALL is irrelevant to binary distributions rm -f $(TMP)/install.txt if [ -e $(BINZIP) ]; then rm $(BINZIP); fi export name=`pwd`/$(BINZIP); cd $(TMP); zip -D -X -9 -R $$name '*' rm -rf $(TMP) printf 'DeuTex %s\nhttp://www.teaser.fr/~amajorel/deutex/'\ "$(VERSION)" | zip -z $(BINZIP) # save - your daily backup save: tar -czvf ../deutex-`date '+%Y%m%d'`.tar.gz\ --exclude dostmp1 --exclude unixtmp1\ --exclude "*~" --exclude "*.o"\ --exclude "*.os" --exclude "*.ot"\ --exclude "*.osd" --exclude "*.otd"\ --exclude "*.obj" . # help - display list of interesting targets help: @echo "Targets for end users:" @echo " [all] Build DeuTex and DeuSF" @echo " install Install DeuTex, DeuSF and the doc" @echo @echo "Targets for developers:" @echo " doc Just the doc" @echo " dall Alias for ddeutex + ddeusf" @echo " ddt Alias for ddeutex" @echo " dds Alias for ddeusf" @echo " ddeutex Debug version of DeuTex -> ./deutex" @echo " ddeusf Debug version of DeuSF -> ./deusf" @echo " dist Source dist. (Unix) -> ./deutex-VERSION.tar.gz" @echo " distdos Source dist. (DOS) -> ./dtexVERSION.zip" @echo " distbindos Binary-only dist. (DOS) -> ./deutex-VERSION.bin.dos.zip" @echo " save Backup archive -> ../deutex-YYYYMMDD.tar.gz" @echo " strip Strip ./deutex and ./deusf" @echo " test Run all tests (long)" @echo " clean Remove executables and object files" deutex-4.4.902/configure0000755000324500032450000002644110305373421014504 0ustar aymaym00000000000000#!/bin/sh # # configure - configure script for DeuTex # AYM 2005-08-17 # # This file is copyright André Majorel 2002-2005. # # This program is free software; you can redistribute it and/or modify it under # the terms of version 2 of the GNU General Public License as published by the # Free Software Foundation. # # 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., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. set -e APPNAME=deutex VERSION=`cat VERSION` AWK=awk CC= # On HP-UX 11.11, /bin/sh unsetting an unset variable returns 1 # On HP-UX 11.11 "x= unset x" is equivalent to "x=; unset x". Same with # Bash 3.0 except when invoked through #!/bin/sh, in which case it's # equivalent to "x=". CFLAGS= unset CFLAGS HAVE_INTTYPES= unset HAVE_INTTYPES HAVE_SNPRINTF= INTTYPES= LDFLAGS= PREFIX=/usr/local tmpdir="$TMPDIR" [ -n "$tmpdir" ] || tmpdir=/tmp cbasename=${APPNAME}_$$.c obasename=${APPNAME}_$$.o ebasename=${APPNAME}_$$ cout=${APPNAME}_$$.out cerr=${APPNAME}_$$.err # # check - perform a test (given C code compiles and links) # check () { printf '%s' "$3" >"$tmpdir/$cbasename" printf 'checking %s...' "$1" if ( cd "$tmpdir" && "$CC" $CFLAGS -o $obasename -c $cbasename && "$CC" $LDFLAGS -o $ebasename $obasename ) >"$tmpdir/$cout" 2>&1 then echo " yes" eval "$2=1" return 0 else echo " no" sed 's/^/> /' "$tmpdir/$cout" eval "$2=" return 1 fi } # # genbool - generate a boolean macro definition # genbool () { name=$1 if [ -n "`eval echo \\$HAVE_$name`" ]; then echo "#define HAVE_$name" else echo "#undef HAVE_$name" fi } # # genh - generate config.h # genh () { pathname=$BUILDDIR/config.h echo generating $pathname ( set -e echo '/* DO NOT EDIT -- generated by ./configure */' echo genbool INTTYPES genbool SNPRINTF [ -z "$INTTYPES" ] || printf '\n%s\n' "$INTTYPES" ) >$pathname } # # fatal - abort with an error message to stderr # fatal () { printf 'configure: %s\n' "$@" >&2 exit 1 } # # Parse the command line # while [ "$#" -ge 1 ] do case "$1" in --help) cat <&2 exit 1 ;; *) echo "configure: too many arguments" 1>&2 exit 1 esac shift done # # Sanity checks # if expr "x$PREFIX" : x/ >/dev/null then true else echo "configure: --prefix: argument is not an absolute path" 1>&2 exit 1 fi # Solaris /bin/grep doesn't know about -Fx. GREP=/usr/xpg4/bin/grep [ -x $GREP ] || GREP=grep # # Look for a C compiler # # We try "gcc" first as commercial Unixen often have a bundled # "cc" command that's useless for our purposes (antiquated KNR # compiler or front-end that just hangs waiting for an answer from # some licence manager). # printf "looking for a C compiler..." if [ -n "$CC" ] then printf ' using user-supplied value:' else CC=gcc if type $CC >/dev/null 2>&1 then set | $GREP -q '^CFLAGS=' || CFLAGS='-O2 -Wall' else CC=c89 if type $CC >/dev/null 2>&1 then set | $GREP -q '^CFLAGS=' || CFLAGS=-O else CC=cc if type $CC >/dev/null 2>&1 then set | $GREP -q '^CFLAGS=' || CFLAGS=-O else echo " none" echo "error: none of (gcc, c89, cc) work, is your PATH set right?" 1>&2 exit 1 fi fi fi fi echo " $CC" # # does the C compiler actually work ? # printf "checking whether the C compiler works..." ( cd "$tmpdir" echo 'main (int argc, char *argv[]) { return 0; }' >$cbasename if ( "$CC" $CFLAGS -o $obasename -c $cbasename && rm -f $ebasename && "$CC" $LDFLAGS -o $ebasename $obasename && ./$ebasename ) >$cout 2>&1 then echo " yes" else echo " no" sed 's/^/> /' $cout echo "error: looks like the C compiler is not working" 1>&2 exit 1 fi ) # # Do we have snprintf() ? # check "for snprintf" HAVE_SNPRINTF ' #include int main (int argc, char *argv[]) { char buf[1]; int n = snprintf (buf, sizeof buf, "%d", 42); return n; } ' || true # # Do we have inttypes.h ? # printf 'checking for inttypes.h...' if [ -n "$HAVE_INTTYPES" ] then echo " yes (forced)" elif set | $GREP -q '^HAVE_INTTYPES=' then echo " no (forced)" else if ( cd "$tmpdir" && cat <<\EOF >$cbasename && #include #include #define CHECKSIZE(type, size) \ do \ { \ printf ("%s %u\n", #type, (unsigned) sizeof (type)); \ if (sizeof (type) != (size)) \ { \ fflush (stdout); \ fprintf (stderr, "inttypes: size of %s is %u, expected %u\n", \ #type, (unsigned) sizeof (type), (unsigned) (size)); \ status = 1; \ } \ } \ while (0) int main (int argc, char *argv[]) { int status = 0; CHECKSIZE (int8_t, 1); CHECKSIZE (int16_t, 2); CHECKSIZE (int32_t, 4); CHECKSIZE (uint8_t, 1); CHECKSIZE (uint16_t, 2); CHECKSIZE (uint32_t, 4); return status; } EOF "$CC" $CFLAGS -o $obasename -c $cbasename && rm -f $ebasename && "$CC" $LDFLAGS -o $ebasename $obasename && ./$ebasename ) >"$tmpdir/$cout" 2>&1 then echo " yes" HAVE_INTTYPES=1 else echo " no" fi fi # # If we don't have , make our own definitions for # {int,uint}{8,16,32}_t # if [ -z "$HAVE_INTTYPES" ] then printf 'guessing at appropriate types for {int,uint}{8,16,32}_t...' if ( cd "$tmpdir" && cat <<\EOF >$cbasename && #include #include int main (int argc, char *argv[]) { assert (sizeof (signed char) == 1); puts ("typedef signed char int8_t;"); assert (sizeof (short) == 2); puts ("typedef short int16_t;"); if (sizeof (long) == 4) puts ("typedef long int32_t;"); else if (sizeof (int) == 4) puts ("typedef int int32_t;"); else fprintf (stderr, "no 32-bit signed type (sizeof (long) = %u, sizeof (int) = %u)\n", (unsigned) sizeof (long), (unsigned) sizeof (int)); assert (sizeof (unsigned char) == 1); puts ("typedef unsigned char uint8_t;"); assert (sizeof (unsigned short) == 2); puts ("typedef unsigned short uint16_t;"); if (sizeof (unsigned long) == 4) puts ("typedef unsigned long uint32_t;"); else if (sizeof (unsigned int) == 4) puts ("typedef unsigned int uint32_t;"); else fprintf (stderr, "no 32-bit unsigned type (sizeof (unsigned long) = %u, sizeof (unsigned)" " = %u)\n", (unsigned) sizeof (unsigned long), (unsigned) sizeof (unsigned int)); return 0; } EOF "$CC" $CFLAGS -o $obasename -c $cbasename && rm -f $ebasename && "$CC" $LDFLAGS -o $ebasename $obasename && ./$ebasename >$cout 2>$cerr ) then echo " success" INTTYPES=`cat "$tmpdir/$cout"` else echo " failure" cat "$tmpdir/$cerr" echo 'Report this bug to the maintainer!' exit 1 fi fi # # Locate a POSIX-compatible awk(1) # printf "checking for a standard-compliant awk..." if ( cd "$tmpdir" && echo a | $AWK '{ print sub(/^a/, "b") $0 }' >$cout 2>&1 && [ "x`cat $tmpdir/$cout`" = "x1b" ] ) then echo " yes" else AWK=/usr/xpg4/bin/awk if ( cd "$tmpdir" && echo a | $AWK '{ print sub(/^a/, "b") $0 }' >$cout 2>&1 && [ "x`cat $tmpdir/$cout`" = "x1b" ] ) then echo " yes ($AWK)" else echo " no" fatal "no suitable awk found, is your PATH set right?" fi fi # # Create the directory where the build-specific files go # SYSTEM_RAW=`uname -n`_`uname -a | cksum` SYSTEM=`echo "$SYSTEM_RAW" | tr -dc '[:alnum:]._-'` BUILDDIR=src echo "build directory is $BUILDDIR" [ -d $BUILDDIR ] || mkdir -p $BUILDDIR # # FHS paths # if expr "$PREFIX" : '//*usr/*$' >/dev/null then BINDIR=/usr/bin # FHS-ly correct is /usr/games ETCDIR=/etc/$APPNAME/%v ETCDIRNV=/etc/$APPNAME MANDIR=/usr/share/man SHAREDIR=/usr/share/games/$APPNAME/%v SHAREDIRNV=/usr/share/games/$APPNAME elif expr "$PREFIX" : '//*usr//*local/*$' >/dev/null then BINDIR=/usr/local/bin # FHS-ly correct is /usr/local/games ETCDIR=/etc/$APPNAME/%v ETCDIRNV=/etc/$APPNAME MANDIR=/usr/local/man SHAREDIR=/usr/local/share/games/$APPNAME/%v SHAREDIRNV=/usr/local/share/games/$APPNAME elif expr "$PREFIX" : '//*opt/*$' >/dev/null then echo '/opt ? Surely you mean /opt/something, Mr. Feynman !' 1>&2 exit 1 elif expr "$PREFIX" : '//*opt//*[^/]' >/dev/null then BINDIR=$PREFIX/bin ETCDIR=/etc/opt/`expr "$PREFIX" : '//*opt//*\(.*\)'` ETCDIRNV= MANDIR=$PREFIX/man SHAREDIR=$PREFIX/share SHAREDIRNV= else # Probably /home/joe/* BINDIR=$PREFIX/bin ETCDIR=$PREFIX/etc ETCDIRNV= MANDIR=$PREFIX/man SHAREDIR=$PREFIX/share SHAREDIRNV= fi # # Write Makefile.config # echo generating Makefile ( echo "# DO NOT EDIT -- generated by ./configure" echo echo "AWK = $AWK" echo "BINDIR = $BINDIR" echo "CC = $CC" echo "CFLAGS = $CFLAGS" echo "ETCDIR = $ETCDIR" | sed "s/%v/$VERSION/g" echo "ETCDIRNV = $ETCDIRNV" echo "HAVE_INTTYPES = $HAVE_INTTYPES" echo "HAVE_SNPRINTF = $HAVE_SNPRINTF" echo "LDFLAGS = $LDFLAGS" echo "MANDIR = $MANDIR" echo "SHAREDIR = $SHAREDIR" | sed "s/%v/$VERSION/g" echo "SHAREDIRNV = $SHAREDIRNV" echo cat Makefile.in ) >Makefile # # Write config.h # genh exit 0 deutex-4.4.902/dos/0000755000324500032450000000000010305373425013357 5ustar aymaym00000000000000deutex-4.4.902/dos/buildbc.bat0000644000324500032450000000162110301352527015447 0ustar aymaym00000000000000@echo off rem buildbc.bat - build DeuTex with Borland C++ rem AYM 1999-09-09 if "%1" == "" goto usage if not "%2" == "" goto usage set bcdir=%1 cd src echo Generating config.h echo #undef HAVE_INTTYPES >config.h echo #undef HAVE_SNPRINTF >>config.h echo typedef signed char int8_t; >>config.h echo typedef short int16_t; >>config.h echo typedef long int32_t; >>config.h echo typedef unsigned char uint8_t; >>config.h echo typedef unsigned short uint16_t; >>config.h echo typedef unsigned long uint32_t; >>config.h echo Building DeuTex bcc -mh -I%bcdir%include -L%bcdir%lib -DDeuTex -e..\deutex.exe *.c echo Building DeuSF bcc -mh -I%bcdir%include -L%bcdir%lib -DDeuSF -e..\deusf.exe *.c cd .. goto end :usage echo Usage: buildbc (dir) echo (dir) The directory where Borland C is installed, echo followed by a backslash (E.G. "c:\bc4\"). :end deutex-4.4.902/dos/builddj.bat0000644000324500032450000000172410301377246015471 0ustar aymaym00000000000000@echo off rem builddj.bat - build DeuTex with DJGPP 2 rem AYM 2005-08-19 echo Generating Makefile echo AWK = awk >Makefile echo BINDIR = /usr/local/bin >>Makefile echo CC = cc >>Makefile echo CFLAGS = -O2 -Wall >>Makefile echo HAVE_INTTYPES = >>Makefile echo HAVE_SNPRINTF = >>Makefile echo LDFLAGS = >>Makefile echo MANDIR = /usr/local/man >>Makefile type Makefile.in >>Makefile echo Generating config.h echo #undef HAVE_INTTYPES >src\config.h echo #undef HAVE_SNPRINTF >>src\config.h echo typedef signed char int8_t; >>src\config.h echo typedef short int16_t; >>src\config.h echo typedef long int32_t; >>src\config.h echo typedef unsigned char uint8_t; >>src\config.h echo typedef unsigned short uint16_t; >>src\config.h echo typedef unsigned long uint32_t; >>src\config.h echo Building DeuTex and DeuSF bash -c 'make SHELL=`type -p bash`' deutex-4.4.902/dos/buildmsc.bat0000644000324500032450000000114710301352640015644 0ustar aymaym00000000000000@echo off rem buildmsc.bat - build DeuTex with MSC rem AYM 1999-09-09 cd src echo Generating config.h echo #undef HAVE_INTTYPES >config.h echo #undef HAVE_SNPRINTF >>config.h echo typedef signed char int8_t; >>config.h echo typedef short int16_t; >>config.h echo typedef long int32_t; >>config.h echo typedef unsigned char uint8_t; >>config.h echo typedef unsigned short uint16_t; >>config.h echo typedef unsigned long uint32_t; >>config.h echo Building DeuTex cl -AH -W2 -DDeuTex -Fe..\deutex.exe *.c echo Building DeuSF cl -AH -W2 -DDeuSF -Fe..\deusf.exe *.c cd .. deutex-4.4.902/old/0000755000324500032450000000000010305373425013350 5ustar aymaym00000000000000deutex-4.4.902/old/deusf.ide0000644000324500032450000007174006065122634015154 0ustar aymaym00000000000000Borland C++ Project File ²º¾úÎoPb(¶X¶Ç>o* É&……ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ                            # $ % & ¨   ©!  ' ( ) * + "  èŽ tex58 èŽ0¨C:\BC45\INCLUDE\DIR.HH 莩c0há莪.莫.def莬.rtf莭.h莮.hrc莯.rhŸèް.inc莱.asi莲.obj莳.lib莴.res莵.apxèŽ$¶ AppExpertDllèŽ(·StripAutoDependsèŽ,¸Remove &AutoDependsQèŽ@¹)Remove all [AutoDepend] nodes from a node莺 .cpp莻.rc/莼 .exe莽 .dll莾.c莿.casèŽÀ.asmèŽ$Á [Internal]eèŽÂ$TASMèŽ Ã$IMPLIB±èŽ<Ä"$NOSWAP $CAP MSG(HC312MSG) $EDNAME©èŽÅ.hlpèŽÆ.hpjèŽtÇ\$NOSWAP $CAP MSG(BORL2MSG.DLL) +$RSP(-I$INC -D1;$DEF -o$OUTNAME) $NAME($EDNAME)$EXT($EDNAME)èŽÈ.ioèŽÉ$ARGSèŽ Ê$EDNAMEaèŽË.kbèŽÌ.dlgèŽÍ.txtèŽ(ÎAppExpertDll.c½èŽ Ïtdw.exe³èŽ(Ð$TD $EXENAME $ARGèŽ(Ñ&Turbo Debugger¡èŽ<Ò%Turbo Debugger on current target nodeèŽ,Ó$TD -l $EXENAME $ARGèŽÔb.exeèŽ4Õ-m"goto_line $LINE" $EDNAMElèŽ$Ö workshop.exeèŽ(×-I$INC $EDNAMEVèŽØ.icoèŽÙ.bmpèŽÚ.mnuèŽÛ.strèŽÜ.curèŽÝ.fonèŽÞICONèŽ ßBITMAPvèŽ àDIALOG×èŽáMENUèŽ$â STRINGTABLEÈèŽ ãCURSOR¿èŽ$ä ACCELERATOR·èŽåFONT:èŽ æ-I$INC§èŽ ç$OUTNAMEèŽ ègrep.comèŽPé7-n+ $NOSWAP$CAP MSG(GREP2MSG.DLL)$PROMPT void $SELNODESèŽ$ê winsight.exeèŽ(ë winspctr.exeèŽdìM$SAVE CUR$NOSWAP $CAP MSG(BORL2MSG.DLL) $EDNAME $NAME($OUTNAME)$EXT($OUTNAME)èŽí.ckbèŽ î OwlCovertèŽ$ï owlcvt.exeSèŽ(ðConvertOWL1SourceèŽLñ3+$RSP($OWLCVT) $SELNODES $CAP MSG(BORL2MSG) $NOSWAP@èŽLò4Convert currently selected nodes from OWL 1 to OWL 2èŽ$ó register.exeèŽ,ô$TARGET -RegServerêèŽDõ,Register the current target as an OLE serverèŽ,ö$TARGET -UnregServerèŽ0÷&Unregister OLE ServerÃèŽHø.Unregister the current target as an OLE server·èŽùdeusfèŽ$ú ASFN:deusf0žèŽ ûDEUSF.C•èŽ(ü«AutoDepReferenceèŽ ýdeutexèŽþidentèŽ ÿlistdirïèŽ mergeèŽ mkwadèŽ toolsèŽ  TOOLS.CèŽ   DEUTEX.HèŽ0  C:\BC45\INCLUDE\STDLIB.HèŽ0  C:\BC45\INCLUDE\_DEFS.HèŽ0  C:\BC45\INCLUDE\_NULL.HÖèŽ0  C:\BC45\INCLUDE\STDIO.HÊèŽ0  C:\BC45\INCLUDE\_NFILE.HèŽ0  C:\BC45\INCLUDE\STRING.HèŽ  TOOLS.H¦èŽ0 C:\BC45\INCLUDE\ALLOC.HžèŽ0 C:\BC45\INCLUDE\UTIME.HèŽ, C:\BC45\INCLUDE\IO.HèŽ0 C:\BC45\INCLUDE\STDARG.HèŽ0 C:\BC45\INCLUDE\TIME.HpèŽ0 C:\BC45\INCLUDE\CTYPE.HèŽ  TEXT.HèŽ4 C:\BC45\INCLUDE\SYS/STAT.H èŽ4 C:\BC45\INCLUDE\SYS/TYPES.HôèŽ  MKWAD.CçèŽ  MKWAD.HßèŽ  IDENT.H×èŽ  MERGE.CÏèŽ   TEXTURE.HèŽ  LISTS.H¿èŽ  MERGE.HèŽ0 C:\BC45\INCLUDE\FCNTL.H èŽ   LISTDIR.CèŽ  IDENT.CÿèŽ  DEUTEX.CèŽ  EXTRACT.HèŽ! chèèŽ$"  BCW4 DefaultèŽ# listsèŽ $ textureÓèŽ %  TEXTURE.CèŽ & LISTS.C¹èŽ ' extractuèŽ (  EXTRACT.CèŽ ) COLOR.HeèŽ *  PICTURE.HèŽ + SOUND.HU(NnžºÒî &B^z–²Îê*R~¾Úö.Jf‚¦Ââ:VÊæ">Zvž¾æJv’Æê . J f ‚ ž º Ö ö  2 V v š ¶ Ö ö  f Š ²  2 R v ž ê 6 Z † Ê ö &nŠ®Îö2RnŠ¦ÆæFv¦Ö&V†²âBb–Êê *JjŠªÚú:Zvš¶Öö6Vv–È=˜˜¶Ç>È"/ÖÈ"O//È"'.4/FÈ"§)P/@`h$ù~¿-È"l/ è," ô/O–´§üÞÿý %&ÿ©·ï³¶ ´$½À®ª«¯¬­µ#ü  7-3./"ðõ‰4*5*6*7*8*9*:*;*<*=*>*?*y*z*¹º»¼úûd‚vxu|†„b€Šy…k‹ˆhefg•c[‘’”–—d]^zwŽs{m˜~o‡ƒ}q“n™›œžŸ ¡¢£°§¢s£²¦¤±¥¸¿öõðóøú ñͰ™‚ …„@–ŒŠ‹ƒ‡•˜ùôòŽ‘’“”—÷× Ö Ú Ø Ù œ› Ft{qöˆù è, ÈÔ/ O–@ 2.C:\BC45\INCLUDE/ C:\BC45\LIBõ deusf.csm è, É O–\ Ns§£¢²¦¤d±¥ è, ÊO–D6s§£¦¢ è,ËO– s§ è,ÌO–$ ´Í è,ÍO–$ ´Í è,ÎO–  Í è,ÏO–,3__DEBUG=2;__TRACE;__WARN è,Ð O– `h$ùrŠ¿-O– Ǹ‘" Ò*sg„4 /O–  hÙ è,úx / O–¬ Ÿ3DeuSFý´¢£¦§¤±²¥t..-\BIN˜•Íóõ..\DEUTEX.CSMüôö€¸g„$!üp /+ g„"ü#O–# @ûÿÿÿÿÈ"$G5u¬/;h`h$%ývò¿-`h$&þwò¿-`h$'ÿxò¿-`h$( yò¿-`h$) zò¿-`h$* {ò¿-O– +” 9~‰ îu‰ @&q @&q @&q @&q @&q @&q ™î @&q¨@&q @&q @&q @&q @&q @&q @&q @&qO– ,ò¾‘£ˆ\sg„-üL/.O–ˆ.| »¾‘ @&q @&q @&q @&q @&q @&q îu‰ @&q @&q @&q @&q ™î Û¾‘ ½›ŒO– /C¿‘DØWsg„0ü/1O–ˆ1| <¿‘ îu‰ @&q @&q @&q @&q @&q @&q ™î Û¾‘ 盌 ½›Œ Ñ›Œ Õ›Œ @&qO– 2i’92dsg„3üÔ/4O–p4d@  F’ îu‰ @&q @&q @&q @&q @&q @&q ™î Û¾‘ 盌 ½›ŒO– 5F¿‘¬Z†sg„6ü€/7O–p7d  ¹‘ îu‰ @&q @&q @&q @&q @&q @&q ™î Û¾‘ 盌 ½›ŒO– 8k’Éø™sg„9ü,/:O–x:l@  Z’ îu‰ @&q @&q @&q @&q @&q @&q @&q ™î Û¾‘ Õ›Œ ­›Œ`h$;© s¿- `h,<! 0$|R¿-ç1s`h,=# $}ò¿- }`h$>$ ô~ò¿-O– ?é9bg„@ü€/AO–pAd % `w‰ îu‰ @&q @&q @&q @&q @&q @&q ™î •î Û¾‘ 盌O– Bð¾‘I"5g„Cü,/DO–hD\ & Ù…‰ îu‰ @&q @&q @&q @&q @&q @&q ™î Û¾‘ Ñ›Œ`h,Eý>Ç.¿-÷(`h,F' <$€ò¿-Ç&€O– G뾑ag„Hü(/IO–I„( Vw‰ îu‰ @&q @&q @&q @&q @&q @&q ™î •î Û¾‘ 盌 ½›Œ) ¥›Œ* Ý›Œ+ 䛌`h$J ¿-`h$K ‚¿-4Plˆ¬Èô¨Ô@œÈ 8X„¨Ôø$DpœÈÔø 4 L x $ H d | ˜ ¼ à  ( L p 0LÔô˜¸ÔDd€ð,¤Èô Dd€ð,”Àì (¸ÜŒ(TЄ¶Ç>! ¿-4U$ªúÿÿÿª4U$,þÿÿÿæÇ2-ÌàT.þÿÿÿ-/ F! ÌàT0þÿÿÿ-1 .!ÌàT2þÿÿÿ-3 /!ÌàT4þÿÿÿ-5"ÌàT6þÿÿÿ-78‘-$ÌàT·þÿÿÿ-¸¹(F!!4U$ 9þÿÿÿêÇ2)-ÌàT ;þÿÿÿ-<=gF# ' ÌàT >þÿÿÿ-?@hF#h'. W"*¿- ÌàT Aþÿÿÿ-BCiF$ +ÌàT Dþÿÿÿ-EF`F$ ,ÌàTGþÿÿÿ-HIkF# - ÌàTJþÿÿÿ-KLjF# . 4U$MþÿÿÿªÇ20-ÌàTOþÿÿÿ-PQa-"„'.ï?/ÌàTRþÿÿÿ-STb-"14U$UþÿÿÿnÇ23-ÌàTWþÿÿÿ-XYQFS24U$_þÿÿÿ2Ç25-ÌàTaþÿÿÿ-bcc/"44U$iþÿÿÿÇ>8ÁÌàTkþÿÿÿÁÂlmeF#6 4U$nþÿÿÿÇ>:oÌàTpþÿÿÿoÃqrd/$94U${þÿÿÿ†Ç>=|ÌàT}þÿÿÿ|Ä~lF$;4U$dþÿÿÿJÇ>?eÌàTfþÿÿÿeÇghF$>4U$€ýÿÿÿVÇ<A-ÌàT ‚ýÿÿÿ-Ƀ„-@ÌàT!…ýÿÿÿ-Ɇ‡‘-B4U$"ˆýÿÿÿrO@G-ÌàT#Šýÿÿÿ-Ê‹Œ0Fì'."ç5C4U$$ýÿÿÿïJ-ÌàT%ýÿÿÿ-‘A$H4U$&’ýÿÿÿê6LÏÌàT'“ýÿÿÿÏÐÑÒ’1&KÌàT(•ýÿÿÿÏÓ–—’&M4U$)˜ýÿÿÿ¾o*OÔÌàT*™ýÿÿÿÔš›F)NÌàT+œýÿÿÿÔÕšžF)PÌàT,ŸýÿÿÿÔÊš¡F)Q4U$-¢ýÿÿÿ* o*aÖÌàT.£ýÿÿÿÖפ¥P-RÌàT/¦ýÿÿÿÖæ§¨ -b4U$0©ýÿÿÿî o*dªÌàT1«ýÿÿÿªç¬­0c4U$2®ýÿÿÿ² o*f-ÌàT3®ýÿÿÿ-ʱ²€2e4U$4³üÿÿÿv o*gèÌàX5´üÿÿÿèéµ¶ 44U$6·üÿÿÿ: o*hêÌàT7¸üÿÿÿ깺 64U$8»üÿÿÿþ o*iëÌàT9¼üÿÿÿë½¾ 84U$:Zþÿÿÿ o*k[ÌàT;Zþÿÿÿ[ì]^1F$:j.4U$<îþÿÿÿ† o*mïÌàT=ðþÿÿÿïñÀòF$<l4U$>ÂþÿÿÿJ o*oóÌàT?ÂþÿÿÿóôÃõ-$>n4U$@Åþÿÿÿ o*qóÌàTAÅþÿÿÿóö÷ø-$@p(LpÄlÀhŒà4ˆÜ0„¨üPtÈì@d¸Ü0T¨Ì D˜ì d ˆ Ü T ¨ Ì t È ì @ ” ¸ 0 „ ¨ $xœðhŒàX|îd  ^¶Ç>‡> ÉÆ--      !"#$%&'()*+,-.^4 '.#^43¨'.^4^4 l'.^4«  '.#^4¬^4­ '.#Ä'.^4 ®^4 ¯ '.#^4 °^4 ±^4 ²'.^4³'.^4´.^4µ^4¶ 3¨'.^4º" '.# ^4»#ì '..^4¼>Ç2$ ¨'.^4½%.ü'.^4¾ zÇ2& '.#à'. ^4¿(à'. ^4À7 '.#^4Å^4Æ< '.#^4È^4ËD '.#;^4ÌEì '..^4ÍF '.#^4ÎI^4 ØS.^4!ÙT.^4"Ú U.^4#ÛV.^4$ÜW.^4%ÝX.^4&ÞY.^4'ßZ.^4(à[.^4)á\.^4*â].^4+ã$^.^4,ä_.^4-å `.^4.íâJ~²æN‚¶êR†ºî"Vоò&ZŽÂö*^’Æú.b–Êþ2fšÎ 6 j ž Ò Pi(fb¶Ç>ß+È/ É:   (d(~z¶Ç>®ß+ˆ/ ÉR%&'()*=>;<EFJK(Àb(ì¼0¶Ç>(O'h¬Döÿÿÿˆ/§; O– h¬Döÿÿÿ¼Ô/8tO– h¬Döÿÿÿ¤/;h¬Döÿÿÿð/8 ˜ /%O– h¬DöÿÿÿD/5¼ /&h¬D  öÿÿÿ È/<h¬D  öÿÿÿ˜/2à /'O– h¬D  öÿÿÿÔ//  /(h¬D  öÿÿÿð/Bô/=h¬Döÿÿÿ/, ( /)h¬Döÿÿÿ”/Eh¬Döÿÿÿø/L /*h¬DöÿÿÿD/?  />O– h¬Döÿÿÿì/GÀ/Fh¬Döÿÿÿ¸/JO– h¬Döÿÿÿ°Ü/KO– (lx¼È P\ ä(4x¼DˆÌØ`l°ÿ—62¶Ç>ß+ ɰc :6¶Ç> É °c 62¶Ç>º( É  ¼ž –’¶Ç>Úß* Év  "$&)-02468:<>@¬¶ :6¶Ç> É W„ JF¶Ç> É* #*+,W„62¶Ç> ÉVJF¶Ç>Êß* É*¬¶JF¶Ç> É*    W„b^¶Ç> ÉB     #%*+,W„62¶Ç> ÉW„:6¶Ç> É#W„62¶Ç> ÉW„62¶Ç> ÉW„:6¶Ç> É#¬¶>:¶Ç> É W„62¶Ç> ÉW„B>¶Ç> É"W„>:¶Ç> É./¬¶:6¶Ç> ÉW„62¶Ç> ÉW„62¶Ç> ɬ¶:6¶Ç> ÉW„ZV¶Ç> É:  !%'(3?AW„ FB¶Ç> É& 3?A¬¶!JF¶Ç> É*!W„"b^¶Ç> ÉB"    #*+,=W„#RN¶Ç> É2##*+,./W„$ZV¶Ç>Êß* É:$  !%'(/?AW„%VR¶Ç> É6% %./?AW„&b^¶Ç>Þß* ÉB&     #*+,¬¶'B>¶Ç> É"'W„(:6¶Ç> É(  V)JF¶Ç>Šß* É*)    ¬¶*>:¶Ç>ª—+ É*¬¶+>:¶Ç> É+¬¶,>:¶Ç> É,¬¶->:¶Ç> É-¬¶.>:¶Ç> É.¬¶/B>¶Ç>þï7 É"/V0:6¶Ç>Jß* É0¬¶162¶Ç> É1¬¶262¶Ç> É2V362¶Ç>šß* É3¬¶462¶Ç> É4V562¶Ç>Zß* É5¬¶662¶Ç> É6W„7FB¶Ç> É&7#*+,V862¶Ç>’ß* É8¬¶9>:¶Ç> É9V:62¶Ç>Rß* É:¬¶;62¶Ç> É;W„<JF¶Ç> É*<#*+,1V=62¶Ç>ß* É=¬¶>:6¶Ç> É>V?62¶Ç>þß* É?¬¶@:6¶Ç> É@VA:6¶Ç>²ß* ÉA !¬¶B:6¶Ç> ÉB¬¶Cb^¶Ç>ÒG ÉBC  W„D:6¶Ç> ÉD#;W„E:6¶Ç> ÉE#.W„F62¶Ç> ÉF#VG62¶Ç>öß* ÉG#¬¶HFB¶Ç> É&HW„I62¶Ç> ÉI%VJ62¶Ç>šß* ÉJ%¬¶K:6¶Ç> ÉKVL:6¶Ç>Zß* ÉL'(¬¶M:6¶Ç> ÉM¬¶NNJ¶Ç> É.NVO>:¶Ç>ß* ÉO*+,¬¶PNJ¶Ç> É.P¬¶QNJ¶Ç> É.Q¬¶R„€¶Ç> ÉdR !"#$%&'()*+,-W„S:6¶Ç> ÉS./W„T:6¶Ç> ÉT./W„U62¶Ç> ÉU.W„V62¶Ç> ÉV.W„W:6¶Ç> ÉW./W„X62¶Ç> ÉX.W„Y62¶Ç> ÉY.W„Z62¶Ç> ÉZ.W„[62¶Ç> É[.W„\62¶Ç> É\.W„]62¶Ç> É].W„^62¶Ç> É^.W„_62¶Ç> É_.W„`62¶Ç> É`.Va:6¶Ç>Æß* Éa./¬¶bNJ¶Ç> É.b! $¬¶c62¶Ç> ÉcVd62¶Ç>ß* Éd1¬¶e:6¶Ç> ÉeVf62¶Ç>*ß* Éf3Vg62¶Ç>¢ß* Ég5Vh62¶Ç>–ß* Éh7Vi62¶Ç>Vß* Éi9¬¶j62¶Ç> ÉjVk62¶Ç>¶ß* Ék;¬¶l62¶Ç> ÉlVm62¶Ç>vß* Ém=¬¶nB>¶Ç> É"nVo62¶Ç>6ß* Éo?¬¶pB>¶Ç> É"pVq62¶Ç>öß* ÉqAÿ—r:6¶Ç>ß+ Érÿ—s62¶Ç>B ( És°ct62¶Ç>îß+ ÉtÈ=uŒˆ¶Ç>O–pud&&¨û                                  % & ( ) * + ÿ—v:6¶Ç>þ( Év9ÿ—w:6¶Ç>~( Éw6ÿ—x:6¶Ç>( Éx 3ÿ—y:6¶Ç>N( Éy 0ÿ—z:6¶Ç>ú( Éz-ÿ—{:6¶Ç>Š( É{!ÿ—|62¶Ç>.ß+ É| ÿ—}:6¶Ç>:( É} Cÿ—~:6¶Ç>¢( É~@ÿ—62¶Ç>Þ ß+ Éÿ—€:6¶Ç>: ß+ É€Hÿ—62¶Ç>ú ß+ Éÿ—‚62¶Ç>J ß+ É‚8… PL¶Ç>| /$¼,„,:˜Ò-T&?d ŠIfðI~nJìZO6O:ÊO6P––P:ÐPJQ6PQJšQJäQbFR6|R:¶R6ìR6"S:\S>šS6ÐSBT>PT:ŠT6ÀT6öT:0UZŠUFÐUJVb|VRÎVZ(WV~WbàWB"X:\XJ¦X>äX>"Y>`Y>žY>ÜYBZ:XZ6ŽZ6ÄZ6úZ60[6f[6œ[Fâ[6\>V\6Œ\6Â\J ]6B]:|]6²]:ì]:&^:`^bÂ^:ü^:6_6l_6¢_Fè_6`6T`:Ž`:È`:aNPa>ŽaNÜaN*b„®b:èb:"c6Xc6Žc:Èc6þc64d6jd6 d6Öd6 e6Be6xe6®e:èeN6f6lf6¢f:Üf6g6Hg6~g6´g6êg6 h6Vh6ŒhBÎh6iBFi6|i:¶i6ìi6"jŒ®l:èl:"m:\m:–m:Ðm: n6@n:zn:´n6ên:$o6Zo6 deutex-4.4.902/old/deutex.ide0000644000324500032450000010446406063153436015346 0ustar aymaym00000000000000Borland C++ Project File ²º¾úÎT„àb(šv‡ß É^““ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øú¨©þÿ                                ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 §ùûü 9 : èŽ § EXTRACT.HèŽ$¨deutexfaultèŽ$© ASFN:deutex1莪.莫.def莬.rtf莭.h莮.hrc莯.rhŸèް.inc莱.asi莲 .obj莳.lib莴.res莵.apxèŽ$¶ AppExpertDllèŽ(·StripAutoDependsèŽ,¸Remove &AutoDependsQèŽ@¹)Remove all [AutoDepend] nodes from a node莺.cpp莻.rc/莼 .exe莽 .dll莾.c莿.casèŽÀ.asmèŽ$Á [Internal]eèŽÂ$TASMèŽ Ã$IMPLIB±èŽ<Ä"$NOSWAP $CAP MSG(HC312MSG) $EDNAME©èŽÅ.hlpèŽÆ.hpjèŽtÇ\$NOSWAP $CAP MSG(BORL2MSG.DLL) +$RSP(-I$INC -D1;$DEF -o$OUTNAME) $NAME($EDNAME)$EXT($EDNAME)èŽÈ.ioèŽÉ$ARGSèŽ Ê$EDNAMEaèŽË.kbèŽÌ.dlgèŽÍ.txtèŽ(ÎAppExpertDll.c½èŽ Ïtdw.exe³èŽ(Ð$TD $EXENAME $ARGèŽ(Ñ&Turbo Debugger¡èŽ<Ò%Turbo Debugger on current target nodeèŽ,Ó$TD -l $EXENAME $ARGèŽÔb.exeèŽ4Õ-m"goto_line $LINE" $EDNAMElèŽ$Ö workshop.exeèŽ(×-I$INC $EDNAMEVèŽØ.icoèŽÙ.bmpèŽÚ.mnuèŽÛ.strèŽÜ.curèŽÝ.fonèŽÞICONèŽ ßBITMAPvèŽ àDIALOG×èŽáMENUèŽ$â STRINGTABLEÈèŽ ãCURSOR¿èŽ$ä ACCELERATOR·èŽåFONT:èŽ æ-I$INC§èŽ ç$OUTNAMEèŽ ègrep.comèŽPé7-n+ $NOSWAP$CAP MSG(GREP2MSG.DLL)$PROMPT void $SELNODESèŽ$ê winsight.exeèŽ(ë winspctr.exeèŽdìM$SAVE CUR$NOSWAP $CAP MSG(BORL2MSG.DLL) $EDNAME $NAME($OUTNAME)$EXT($OUTNAME)èŽí.ckbèŽ î OwlCovertèŽ$ï owlcvt.exeSèŽ(ðConvertOWL1SourceèŽLñ3+$RSP($OWLCVT) $SELNODES $CAP MSG(BORL2MSG) $NOSWAP@èŽLò4Convert currently selected nodes from OWL 1 to OWL 2èŽ$ó register.exeèŽ,ô$TARGET -RegServerêèŽDõ,Register the current target as an OLE serverèŽ,ö$TARGET -UnregServerèŽ0÷&Unregister OLE ServerÃèŽHø.Unregister the current target as an OLE server·èŽùc0h¼èŽ útex58 èŽûchhhèŽütextèŽþtoolsèŽ ÿtextureèŽ substit§èŽ soundèŽ  picture˜èŽ mkwadèŽ mergeèŽ lzw‚èŽ listsèŽ  listdirtèŽ identèŽ gifcodecèŽ extract]èŽ composeUèŽ colorèŽ COLOR.CFèŽ  DEUTEX.HèŽ( |AutoDepReferenceèŽ0 C:\BC45\INCLUDE\STDLIB.HèŽ0 C:\BC45\INCLUDE\_DEFS.H èŽ0 C:\BC45\INCLUDE\_NULL.HèŽ0 C:\BC45\INCLUDE\STDIO.HèŽ0 C:\BC45\INCLUDE\_NFILE.HèŽ0 C:\BC45\INCLUDE\STRING.HèŽ  TOOLS.HÜèŽ  COLOR.HÔèŽ   COMPOSE.CèŽ   MKWAD.HÄèŽ   TEXTURE.HèŽ  IDENT.H´èŽ   PICTURE.HèŽ  SOUND.H#èŽ  DEUTEX.CèŽ  MERGE.HèŽ TEXT.CmèŽ !  EXTRACT.CèŽ$"  GIFCODEC.CôèŽ # IDENT.CëèŽ $  LISTDIR.CèŽ % LISTS.CÛèŽ & LISTS.HÓèŽ' LZW.CèŽ0( C:\BC45\INCLUDE\CTYPE.HÄèŽ ) MERGE.C¸èŽ0* C:\BC45\INCLUDE\FCNTL.HèŽ + MKWAD.C°èŽ,, C:\BC45\INCLUDE\IO.HèŽ4- C:\BC45\INCLUDE\SYS/STAT.HèŽ4. C:\BC45\INCLUDE\SYS/TYPES.HèŽ0/ C:\BC45\INCLUDE\TIME.HèŽ 0  PICTURE.CèŽ 1 SOUND.C®èŽ 2  SUBSTIT.CèŽ 3  TEXTURE.CèŽ 4 TOOLS.C èŽ05 C:\BC45\INCLUDE\ALLOC.H èŽ,6 C:\BC45\INCLUDE\DIR.HèŽ07 C:\BC45\INCLUDE\UTIME.HùèŽ08 C:\BC45\INCLUDE\STDARG.HèŽ 9 TEXT.HeèŽ: DoDo(†¦Êî">Zv’®Êæ:^†²ò*Fb~š¶ÚöRnŠþ6VrŽªÒòB~ªÆú F b ~ š ¶ Ò î * J f Š ª Î ê * J š ¾ æ J f † ª Ò  j Ž º þ *Z¢¾Þú2RrŽ®Êæ>ZzšºÖö>nžÎþ.^~ž¾Þþ>^~ž¾Þ"Bb‚žÎî>jžÒ"Bb‚¢Òþ.^~È=<Pì‡È"_0ÖÈ"W0_0È" 4_0FÈ" P_0@`h$¨~‡ È"Ÿ l_0 è,: ô_0O–´§üÞÿý %&ÿ©·ï³¶ ´$½À®ª«¯¬­µ#ü  7-3./"ðõ‰4*5*6*7*8*9*:*;*<*=*>*?*y*z*¹º»¼úûd‚vxu|†„b€Šy…k‹ˆhefg•c[‘’”–—d]^zwŽs{m˜~o‡ƒ}q“n™›œžŸ ¡¢£°§¢s£²¦¤±¥¸¿öõðóøú ñͰ™‚ …„@–ŒŠ‹ƒ‡•˜ùôòŽ‘’“”—÷× Ö Ú Ø Ù œ› Ft{qöˆù è, ÈÔ_0 O–@ 3.C:\BC45\INCLUDE/ C:\BC45\LIBõ deutex.csm è, É O–\ Ns§£¢²¦¤d±¥ è, ÊO–D6s§£¦¢ è,ËO– s§ è,ÌO–$ ´Í è,ÍO–$ ´Í è,ÎO–  Í è,ÏO–,3__DEBUG=2;__TRACE;__WARN è,Ð O– `h$¨rЇ g„úO– )ÖO– …Œrˆwsg„úh _0 O–   hÙ è,!©¬ _0"O–4"(3DeuTexeutexexen‡&P•ò.,‚Add to Project List¹:ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̹òC:\PROG\DOOM\_DEUTEX_\PICTURE.CÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌC:Ì\PROG\DOOM\_DEUTEX_\ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌPICTUREÌÌ.CÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌQF C++ sourEB deutex.exe*.c;*.cppAll files (*.*)*.*Resource (*.rc)*.rc´$ý¢£¦§¸¤±²¥t..-\BIN õ..\DEUTEX.CSM%ï#u|†kh¢•wŽm‡ƒn¡›™•üôö€˜òŒõÍO– #‡Œû$s‰O–$„@ Úø îu‰ @&q @&q @&q @&q @&q @&q ™î Ù›Œ 盌 ½›Œ ¥›Œ Ý›Œ 䛌9 •îO– %‰ŒL+˜‰O–ˆ&|@ ï~‰ îu‰ @&q @&q @&q @&q @&q @&q( @&q ™î Ù›Œ Õ›Œ§­›Œ ¥›Œ Ý›Œ`h$'þyò‡ `h$(ÿzò‡ `h$) {ò‡ `h$* |ò‡ `h$+ }ò‡ `h$, ~ò‡ `h$- ò‡ `h$. €ò‡ `h$/ ò‡ `h$0 ‚ò‡ `h$1 ƒò‡ `h$2 „ò‡ `h$3 …ò‡ `h$4¨†ò‡ `h$5 ‡ò‡ `h$6 ˆò‡ g„$7 œ_08 O–`8T@ ÜHÁ îu‰ @&q @&q @&q @&q @&q @&q ™î ¥›ŒÈ"9Ï!s¬_0;hO– :‹Œ@æa‰g„;  _0$O– <ŒŒ‰O–X=D@" Ô˜® îu‰ @&q @&q @&q @&q @&q @&qü¸›Œg„> ° _0&O– ?Œ…ˆ‰O–p@d@ # Žˆ‰ îu‰ @&q @&q @&q @&q @&q @&q ™î Ù›Œ 盌 ½›Œg„A ”_0BO–B„@! Vw‰ îu‰ @&q @&q @&q @&q @&q @&q ™î9 •î Ù›Œ 盌 ½›Œ ¥›Œ Ý›Œ 䛌O– CŽŒ‘…b‰g„D t_0=O– EŒã"5‰O–hF\@ % Ù…‰ îu‰ @&q @&q @&q @&q @&q @&q ™î Ù›Œ& Ñ›Œg„G _0@O– H‘Œw ¸f‰O–`IT@ ' æYº îu‰ @&q @&q @&q @&q @&q @&q ™î( @&qg„J  _0KO–pKd@ $  €‰ îu‰ @&q @&q @&q @&q @&q @&q ™î Ù›Œ 盌 ½›ŒO– L’ŒOx:‰g„M €_0FO– N”Œ^@‰O–ˆO|@+ rw‰, @&q @&q @&q- @&q. @&q/ @&q îu‰ @&q @&q @&q @&q ™î Ù›Œ ½›Œg„P $_0IO– Q–Œx"z‰O–€Rl@ 0 ¶  îu‰ @&q @&q @&q @&q @&q @&q ™î Ù›Œ ½›Œ ¥›Œ( @&qü¸›Œg„S Ì_0TO–ˆT|@) bŒ îu‰ @&q @&q @&q @&q @&q @&q ™î Ù›Œ 盌 ½›Œ& Ñ›Œ Õ›Œ* @&qO– U—Œ÷«‰g„V l_0OO– W—Œ£‰O–XXL@ 2 úYº îu‰ @&q @&q @&q @&q @&q @&q ™îg„Y 0_0RO– Z™Œ°Ib‰O–p[d@ 3 `w‰ îu‰ @&q @&q @&q @&q @&q @&q ™î9 •î Ù›Œ 盌g„\ Ð_0]O–p]d@ 1 Ž˜ü îu‰ @&q @&q @&q @&q @&q @&q ™î Ù›Œ 䛌9 •îO– ^šŒ! Ó*‰g„_ °_0X`h,`ù ä&ÿ1u‡ Ç:u`h$aûôvR‡ g„b D_0[`h$c w‡ `h,düäÏ/xò‡ ,xg„e T_0fO– f”@4 9~‰ îu‰ @&q @&q @&q @&q @&q @&q ™î5 @&q6 @&q, @&q7 @&q/ @&q8 @&q( @&q- @&q. @&q`h$g¨‰‡ `h$hÿЇ `h,i 6—"‹‡ g*‹`h$j Œ‡ `h$k ‡ `h$l )*.އ `h$m pAl‡ `h$n ÌQF‡ `h$o ÌÌÌÌ‘‡ `h$p ÌÌÌÌ’‡ `h$qþÌÌÌÌ“‡ `h$rü ”‡ O– s„Œ^º½•g„t è_0uO–hu\@ ã ø îu‰ @&q @&q @&q @&q @&q @&q ™î9 •î( @&q4Plˆ¬Èô¨Ô@œÈ 8X„¨Ôø$DpœÈÔø , L h € ¬ à ° 8\€¤Èì4X| Äè 0Txœü8TtÌèx”$D`€è$„ 0Llô0°ÌTt°$D´Ð@`|¨Ìè 8Tô<hŒ°Ôø@dˆ¬ÌèŒ(TЄ‡W/ ‡ 4U$ªúÿÿÿª4U$,þÿÿÿ²‡-ÌàT.þÿÿÿ-/ F! ÌàT0þÿÿÿ-1 .!ÌàT2þÿÿÿ-3 /!ÌàT4þÿÿÿ-5"ÌàT6þÿÿÿ-78‘-$ÌàT·þÿÿÿ-¸¹(F!!4U$ 9þÿÿÿj W*)-ÌàT ;þÿÿÿ-<=gF# ' ÌàT >þÿÿÿ-?@hF#h ÷ *‡ ÌàT Aþÿÿÿ-BCiF$ +ÌàT Dþÿÿÿ-EF`F$ ,ÌàTGþÿÿÿ-HIkF# - ÌàTJþÿÿÿ-KLjF# . 4U$Mþÿÿÿ* W*0-ÌàTOþÿÿÿ-PQa-"„ !/ÌàTRþÿÿÿ-STb-"14U$Uþÿÿÿî W*3-ÌàTWþÿÿÿ-XYQFS24U$_þÿÿÿ² W*5-ÌàTaþÿÿÿ-bcc/"44U$iþÿÿÿ* W*8ÁÌàTkþÿÿÿÁÂlmeF#6 4U$nþÿÿÿî W*:oÌàTpþÿÿÿoÃqrd/$94U${þÿÿÿb W*=|ÌàT}þÿÿÿ|Ä~lF$;4U$dþÿÿÿ& W*?eÌàTfþÿÿÿeÇghF$>4U$€ýÿÿÿæ W*A-ÌàT ‚ýÿÿÿ-Ƀ„-@ÌàT!…ýÿÿÿ-Ɇ‡‘-B4U$"ˆýÿÿÿî W*G-ÌàT#Šýÿÿÿ-Ê‹Œ0F"C4U$$ýÿÿÿv W*J-ÌàT%ýÿÿÿ-‘A$H4U$&’ýÿÿÿ6 W*LÏÌàT'“ýÿÿÿÏÐÑÒ’1&KÌàT(•ýÿÿÿÏÓ–—’&M4U$)˜ýÿÿÿòW*OÔÌàT*™ýÿÿÿÔš›F)NÌàT+œýÿÿÿÔÕšžF)PÌàT,ŸýÿÿÿÔÊš¡F)Q4U$-¢ýÿÿÿ^W*aÖÌàT.£ýÿÿÿÖפ¥P-RÌàT/¦ýÿÿÿÖæ§¨ -b4U$0©ýÿÿÿ"W*dªÌàT1«ýÿÿÿªç¬­0c4U$2®ýÿÿÿæW*f-ÌàT3®ýÿÿÿ-ʱ²€2e4U$4³üÿÿÿªW*gèÌàX5´üÿÿÿèéµ¶ 44U$6·üÿÿÿnW*hêÌàT7¸üÿÿÿ깺 64U$8»üÿÿÿ2W*iëÌàT9¼üÿÿÿë½¾ 84U$:ZþÿÿÿöW*k[ÌàT;Zþÿÿÿ[ì]^1F$:j.4U$<îþÿÿÿºW*mïÌàT=ðþÿÿÿïñÀòF$<l4U$>Âþÿÿÿ~W*oóÌàT?ÂþÿÿÿóôÃõ-$>n4U$@ÅþÿÿÿBW*qóÌàTAÅþÿÿÿóö÷ø-$@p(LpÄlÀhŒà4ˆÜ0„¨üPtÈì@d¸Ü0T¨Ì D˜ì d ˆ Ü T ¨ Ì t È ì @ ” ¸ 0 „ ¨ $xœðhŒàX|îd  ^‡jÏ ÉÆ--      !"#$%&'()*+,-.^4#^43¨ ^4^4 l ^4« #^4¬^4­ #Ä ^4 ®^4 ¯#^4 °^4 ±^4 ² ^4³ ^4´.^4µ^4¶ 3¨ ^4º"# ^4»#.^4¼¾W*$ ¨ ^4½%.ü ^4¾ú W*&#à ^4¿(à ^4À7#^4Å^4Æ<#^4È^4ËD#;^4ÌE.^4ÍF#^4ÎI^4 ØS.^4!ÙT.^4"Ú U.^4#ÛV.^4$ÜW.^4%ÝX.^4&ÞY.^4'ßZ.^4(à[.^4)á\.^4*â].^4+ã$^.^4,ä_.^4-å `.^4.íâJ~²æN‚¶êR†ºî"Vоò&ZŽÂö*^’Æú.b–Êþ2fšÎ 6 j ž Ò Pi(fb‡ÎO0È_0 É:   !(d(ÆÂ‡²/ˆ_0 Éš""'()*+,-./0123456ghijklmnopq`acdr(Àb(f ü j‡(Ÿ — h¬Döÿÿÿˆ_0¯  O– h¬Döÿÿÿ¼Ÿ  Ô_0Ç!tO– h¬Döÿÿÿ)ô_0gO– h¬Döÿÿÿ-|_0`O– h¬D  öÿÿÿ ¨_0aO– h¬D  öÿÿÿ %è_0cO– h¬D  öÿÿÿ¬_0s3 _0dh¬Döÿÿÿ@_0^1 8_0'h¬Döÿÿÿ_0hh¬Döÿÿÿ$_0Z\_0(O– h¬Döÿÿÿ_0W€_0)h¬Döÿÿÿ'<_0ih¬DöÿÿÿT_0U/¤_0*O– h¬Döÿÿÿ_0Q,È_0+h¬Döÿÿÿ-h_0jh¬DöÿÿÿL_0N ì_0,O– h¬Döÿÿÿ_0L$_0-h¬Döÿÿÿ#Œ_0kh¬Döÿÿÿ_0H4_0.O– h¬Döÿÿÿ`_0E(X_0/h¬D  öÿÿÿ"°_0lh¬D!!öÿÿÿ$_0C|_00O– "h¬D##öÿÿÿè_0?! _01h¬D$$öÿÿÿ&Ô_0mh¬D%%öÿÿÿT_0< #Ä_02O– &h¬D''öÿÿÿ_0:%è_03h¬D((öÿÿÿ*ø_0nh¬D))öÿÿÿ _0%' _04O– *h¬D++öÿÿÿà _0#)0_05h¬D,,öÿÿÿ._0oh¬D--öÿÿÿ, _0+T_06O– .h¬D//öÿÿÿ0@_0pO– 0h¬D11öÿÿÿ2d_0qO– 2h¬D33öÿÿÿ4 ˆ_0rO– 4(lx¼È \h¬¸üLÔ$h¬ðü@„ÈÔ\ ¬ð4x„È P\ ä(4x¼ P \   ¬ ð ÿ—62‡ž/ ɰc :6‡ É °c 62‡ŽG0 É  ¼ž –’‡_* Év  "$&)-02468:<>@¬¶ :6‡ É W„ JF‡ É* #*+,W„62‡ ÉVJF‡¾_* É*¬¶JF‡ É*    W„b^‡ ÉB     #%*+,W„62‡ ÉW„:6‡ É#W„62‡ ÉW„62‡ ÉW„:6‡ É#¬¶>:‡ É W„62‡ ÉW„B>‡ É"W„>:‡ É./¬¶:6‡ ÉW„62‡ ÉW„62‡ ɬ¶:6‡ ÉW„ZV‡ É:  !%'(3?AW„ FB‡ É& 3?A¬¶!JF‡ É*!W„"b^‡ ÉB"    #*+,=W„#RN‡ É2##*+,./W„$ZV‡w) É:$  !%'(/?AW„%VR‡ É6% %./?AW„&b^‡*w) ÉB&     #*+,¬¶'B>‡ É"'W„(:6‡ É(  V)JF‡6_* É*)    ¬¶*>:‡nw) É*¬¶+>:‡ É+¬¶,>:‡ É,¬¶->:‡ É-¬¶.>:‡ É.¬¶/B>‡²* É"/V0:6‡r_* É0¬¶162‡ É1¬¶262‡ É2V362‡^_* É3¬¶462‡ É4V562‡_* É5¬¶662‡ É6W„7FB‡ É&7#*+,V862‡Þ_* É8¬¶9>:‡ É9V:62‡ž_* É:¬¶;62‡ É;W„<JF‡ É*<#*+,1V=62‡‚ _* É=¬¶>:6‡ É>V?62‡B _* É?¬¶@:6‡ É@VA:6‡ _* ÉA !¬¶B:6‡ ÉB¬¶Cb^‡ ÉBC  W„D:6‡ ÉD#;W„E:6‡ ÉE#.W„F62‡ ÉF#VG62‡ _* ÉG#¬¶HFB‡ É&HW„I62‡ ÉI%VJ62‡‚ _* ÉJ%¬¶K:6‡ ÉKVL:6‡B _* ÉL'(¬¶M:6‡ ÉM¬¶NNJ‡ É.NVO>:‡ _* ÉO*+,¬¶PNJ‡ É.P¬¶QNJ‡ É.Q¬¶R„€‡ ÉdR !"#$%&'()*+,-W„S:6‡ ÉS./W„T:6‡ ÉT./W„U62‡ ÉU.W„V62‡ ÉV.W„W:6‡ ÉW./W„X62‡ ÉX.W„Y62‡ ÉY.W„Z62‡ ÉZ.W„[62‡ É[.W„\62‡ É\.W„]62‡ É].W„^62‡ É^.W„_62‡ É_.W„`62‡ É`.Va:6‡ _* Éa./¬¶bNJ‡ É.b! $¬¶c62‡ ÉcVd62‡‚ _* Éd1¬¶e:6‡ ÉeVf62‡B _* Éf3Vg62‡ _* Ég5Vh62‡ _* Éh7Vi62‡‚ _* Éi9¬¶j62‡ ÉjVk62‡B _* Ék;¬¶l62‡ ÉlVm62‡ _* Ém=¬¶nB>‡ É"nVo62‡Â_* Éo?¬¶pB>‡ É"pVq62‡‚_* ÉqAÿ—r:6‡^/ ÉrÈ=süø‡O–àsÔ--§                    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 °ct62‡/ Ét!ÿ—u62‡nß Éuÿ—v62‡:Ï Év ÿ—w62‡"Ï Éw ÿ—x:6‡ZÏ Éx tÿ—y:6‡JG0 Éyeÿ—z:6‡G0 Ézbÿ—{:6‡.G0 É{_ÿ—|:6‡~G0 É|\ÿ—}:6‡.G0 É}Yÿ—~:6‡. G0 É~Vÿ—:6‡Þ G0 ÉSÿ—€:6‡" G0 É€Pÿ—:6‡* G0 ÉMÿ—‚:6‡ú G0 É‚!Jÿ—ƒ:6‡> G0 Ƀ#Gÿ—„:6‡† G0 É„%Dÿ—…:6‡Ê G0 É…'Aÿ—†:6‡:G0 Ɇ)>ÿ—‡:6‡â/ ɇ+;ÿ—ˆ:6‡6G0 Ɉ-7ÿ—‰62‡/ ɉÿ—Š62‡2O0 ÉŠÿ—‹62‡úO0 É‹ÿ—Œ62‡ÂO0 ÉŒÿ—62‡.?/ Éÿ—Ž62‡?/ ÉŽ ÿ—62‡r?/ É$ÿ—62‡ÎO0 É(ÿ—‘62‡Ê?/ É‘,ÿ—’62‡Zß É’/ÿ—“62‡ß É“1ÿ—”62‡ªÏ É”38… à܇ü_09¼¼–,<<x8TÌId 0Tf–TÆ\Uf Â_6ø_:2`6h`–þ`:8aJ‚a6¸aJbJLbb®b6äb:c6Tc6Šc:Äc>d68dBzd>¸d:òd6(e6^e:˜eZòeF8fJ‚fbäfR6gZgVægbHhBŠh:ÄhJi>Li>Ši>Èi>j>DjB†j:Àj6öj6,k6bk6˜k6Îk6lFJl6€l>¾l6ôl6*mJtm6ªm:äm6n:Tn:Žn:Ènb*o:do:žo6Ôo6 pFPp6†p6¼p:öp:0q:jqN¸q>öqNDrN’r„s:Ps:Šs6Às6ös:0t6ft6œt6Òt6u6>u6tu6ªu6àu6v:PvNžv6Ôv6 w:Dw6zw6°w6æw6x6Rx6ˆx6¾x6ôxB6y6lyB®y6äy:zü}6P}6†}6¼}6ò}:,~:f~: ~:Ú~::N:ˆ:Â:ü:6€:p€:ª€:ä€::X:’:Ì6‚68‚6n‚6¤‚6Ú‚6ƒ6Fƒ6|ƒ6²ƒ6èƒ6„6 deutex-4.4.902/old/dos2unix.sh0000755000324500032450000000032506117772276015477 0ustar aymaym00000000000000#! /bin/csh -f # # In case you don't have the dos2unix command: # here is the fastest and simplest solution... # # 08-Mar-96, Jack Leunissen # foreach i ( *.[ch] makefile ) tr -d '\015' < $i > tmp mv tmp $i end deutex-4.4.902/old/save.bat0000644000324500032450000000012705770541400014776 0ustar aymaym00000000000000pkzip -ex ..\dtexsf.zip *.c *.h *.def *.prj *.ide *.bat *.txt *.cmd *.mak *.sh makefiledeutex-4.4.902/scripts/0000755000324500032450000000000010305373426014262 5ustar aymaym00000000000000deutex-4.4.902/scripts/codes0000755000324500032450000001020410304405615015275 0ustar aymaym00000000000000#!/usr/bin/perl -w # # codes - extract message codes from DeuTex source # AYM 2005-08-28 # # This file is copyright André Majorel 2005. # # This program is free software; you can redistribute it and/or modify it under # the terms of version 2 of the GNU General Public License as published by the # Free Software Foundation. # # 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., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. use strict; use File::Basename; use IO::Handle; sub split_args ($); sub err (@); # DeuTex functions that take a message code as argument my %funcs = ( 'Bug' => { class => 'b', code => 0 }, 'Detail' => { class => 'i', code => 0 }, 'Info' => { class => 'i', code => 0 }, 'LimitedEpilog' => { class => 'w', code => 1 }, 'LimitedWarn' => { class => 'w', code => 1 }, 'Phase' => { class => 'i', code => 0 }, 'ProgError' => { class => 'e', code => 0 }, 'Warning' => { class => 'w', code => 0 }, 'nf_err' => { class => 'e', code => 0 }, ); # Used to spot duplicates my %codes; my $status = 0; foreach my $pathname (@ARGV) { my $path = dirname $pathname; my $inc = ''; $inc = "-I$path" if length ($path) > 0; my $pathnameq = $pathname; $pathnameq =~ s/'/'\''/g; # Hide errno because the Glibc headers #define it to something hairy. my $cmd = "sed 's/errno\\([^.]\\)/errno_\\1/g' '$pathnameq'" . " | gcc -DDeuTex $inc -E - | indent -l9999"; my @canonsrc = `$cmd`; if (@canonsrc == 0) { err "$pathname: an error occurred while running indent(1)"; $status = 1; next; } foreach my $lbuf (@canonsrc) { # Function call ? if ($lbuf =~ /^\s*([_a-zA-Z][_a-zA-Z0-9]*)\s*\((.*)\);\s*$/) { next unless exists $funcs{$1}; my $name = $1; my $args = $2; my $hash = $funcs{$1}; # Extract the arguments to the function my @args = split_args $args; # Extract the message code from the arguments. Any arguments # before the code are removed (cf. LimitedWarn()). my $code = splice @args, 0, $hash->{code} + 1; if ($code !~ s/^"([A-Z][A-Z][0-9][0-9])"$/$1/) { err "invalid code \"$code\""; $status = 1; next; } # Report duplicates if (exists $codes{$code}) { err "$pathname: code $code already used in $codes{$code}"; } else { $codes{$code} = $pathname; } printf "%s %s %-13s %s\n", $code, $hash->{class}, $pathname, join ("\t", @args); } } } exit $status; # # split_args - split the arguments of a C function # sub split_args ($) { my ($string) = @_; my @args = (''); my $quote = ''; my $backslash = 0; my $paren = 0; for (my $i = 0; $i < length $string; $i++) { my $c = substr $string, $i, 1; if ($quote eq '') { if ($c eq "'") { $quote = "'"; } elsif ($c eq '"') { $quote = '"'; } elsif ($c eq '(') { $paren++; } elsif ($c eq ')') { $paren--; if ($paren < 0) { err "extra \")\" in \"$string\""; exit 1; } } elsif ($c eq ',' && $paren == 0) { push @args, ''; $c = ''; } elsif ($c =~ /^\s$/ && $paren == 0 && length ($args[@args - 1]) == 0) { $c = ''; } } elsif ($quote eq "'") { if ($c eq '\\' && ! $backslash) { $backslash = 2; } elsif ($c eq "'" && ! $backslash) { $quote = ''; } } elsif ($quote eq '"') { if ($c eq '\\' && ! $backslash) { $backslash = 2; } elsif ($c eq '"' && ! $backslash) { $quote = ''; } } else { err "internal error, invalid quote"; } $args[@args - 1] .= $c; $backslash-- if $backslash > 0; } return @args; } # # err - print an error message # sub err (@) { STDOUT->flush; print STDERR "codes: ", @_, "\n"; return 1; } deutex-4.4.902/scripts/html2txt0000755000324500032450000000057210304415273015776 0ustar aymaym00000000000000#!/bin/sh # # html2txt - convert an HTML document to text # AYM 2005-08-28 # if [ "$#" != 1 ] then echo "Usage: html2txt file" >&2 exit 1 fi set -e echo 'THIS IS A GENERATED FILE -- DO NOT EDIT !' printf 'Edit %s instead.\n\n' "$1" # First time is to catch errors links -dump-width 87 -dump "$1" >/dev/null links -dump-width 87 -dump "$1" | sed 's/^ //; s/^ //' deutex-4.4.902/scripts/process0000755000324500032450000000111207445122472015665 0ustar aymaym00000000000000#!/bin/sh # # process - expand certain macro expressions in text files # Usage: process # AYM 1999-08-13 # # In , replace occurrences of # - "$DATE" by the YYYY-MM-DD current time, # - "$SELF_DATE" by the YYYY-MM-DD mtime of , # - "$VERSION" by the contents of the file ./VERSION. # Output is written on stdout. file=$1 shift sed -e "s/\$DATE/`date +%Y-%m-%d`/ s/\$SELF_DATE/`find $file -printf '%TY-%Tm-%Td'`/ s/\$VERSION/`cat VERSION`/ /\$OPTIONS/ { r unixtmp1/deutex.6.opt d } /\$DIAGNOSTICS/ { r unixtmp1/deutex.6.diag d }" $file deutex-4.4.902/CHANGES0000644000324500032450000007004610305357506013576 0ustar aymaym00000000000000THIS IS A GENERATED FILE -- DO NOT EDIT ! Edit docsrc/changes.html instead. History of changes for DeuTex DeuTex 4.4.902 (AYM 2005-08-31) * Build: vanilla make compatibility: removed all occurrences of "$<" not in inference rules in the makefile. * Build: vanilla make compatibility: removed all "\" followed by empty lines. On NCR MP-RAS, make quotes all empty lines that follow ! * Build: there is now a "./configure" script (GNU autoconf work-alike). Installing somewhere else than /usr/local is now done by giving ./configure the --prefix option. CC, CFLAGS and LDFLAGS are now auto-detected. The defaults can be overridden by passing ./configure the --cc, --cflags and --ldflags options. The fixed-size types (Int16 etc.) are now correctly set on all LP64 platforms, not just Alpha. * Build: the OPTIONS section is now updated automatically. This impacts no-one but hackers. * Code: two char[8] were used as char[9] (caught by NCR/MetaWare cc on NCR MP-RAS). * Code: C89 compatibility: removed a few "//" comments that had slipped into the source. * Code: a few functions were declared as static but defined as extern (caught by NCR/MetaWare cc on NCR MP-RAS). * Code: static- and const-correctness fixes. * Code: removed the little-used Legal() function. * Doc: man page: in DESCRIPTION, added a short list of examples to help new users getting started. Added a FILES section. Made the SEE ALSO section a bit more specific. * Doc: in --help and the man page, divided the options into groups and sorted them alphabetically within each group. It seems to be clearer that way. * Doc: added a FAQ. * Doc: obfuscated all email addresses (tr .@ +=). * Game: Strife: the SCRIPTnn lumps are now extracted in human-readable form into the scripts/ directory. The reverse operation is not implemented. Since we understand the Strife script format only partially, the output format is still in flux. New option -scripts to extract only the scripts. The reverse engineering was done in collaboration with Matthew W. Miller. * Graphics: it's now possible to build wads that use a custom PLAYPAL. Previously, DeuTex always used the PLAYPAL from the iwad when building. It now uses the one in lumps/ if it exists. Thanks to Ras2 for reporting the problem. * Graphics: rewrote COLdiff() as a macro. On my system, the time to build a wad made of a single 1M-pixel patch is down from 1.32s to 0.85s (35% faster), which is not surprising since DeuTex used to spend about 40% of its time in COLdiff(). The time to rebuild the Strife iwad is down from 8.6s to 7.2s (16% faster). * Graphics: removed the "quantisation is slow" warnings that DeuTex used to spew when composing from PPMs and 24-bit BMPs. Those warnings were relevant to an old quantisation algorithm that has not been used since at least version 3.8 (#ifdef QUANTSLOW). * Graphics: lifted the arbitrary limit of 256 patches per texture. DeuTex will now accept as many patches as the wad format allows (32,767). If a texture definition has more than that many patches, DeuTex will discard the excess patches with a warning, instead of dying with a cryptic message like "Line n: Illegal char '*'". * Graphics: lifted the arbitrary limit of 4096 on patch width. DeuTex now handles patches as wide as the wad format allows (32,767). * Graphics: textures wider than 4096 are now accepted with a warning. PrBoom 2.2.3 is known to take textures as wide as 16,384 pixels. 8192 *128 textures make XDoom 20001001 crash in Z_Malloc. 1024 *128 textures make Doom freeze in R_Init. The maximum acceptable widths might be higher if the height of the texture is lesser than 128 but I haven't looked into it. Thanks to David Damerell for testing. * Misc: removed the annoying startup banner. * Misc: if no command is given, emit a meaningful error message instead of suggesting to switch to WinTex. And exit with code 1 instead of 255. * Misc: all messages now look like this : c code string c is the class of the message : "i" for information, "w" for warning, "E" for error, "B" for bug. code is a unique 4-character alphanumeric code which unambiguously identifies the message. Some of the messages have been rewritten to be more informative (mention the filename, the nature of the error, etc.). * Misc: at the request of Kim "Sparky" Parrott, all messages are now copied to a file named "deutex.log" ("deusf.log" for DeuSF). The default log file name can be overridden through the "-log" option. If you don't want a log file, try "-log /dev/null" (Unix) or "-log nul" (DOS). The log is only written if a command that works with wads is given. --help, --version etc. do not create a log. * Misc: removed the 30 command-line arguments limit. * Misc: made exit status a little bit more normal (2 for errors and 3 for bugs instead of -5 and -10). * Sound: new option -rate to specify what DeuTex should do when including sound files whose sample rate is not exactly 11025 Hz. The choices are : reject consider it a fatal error and exit immediately with a non-zero exit code. force emit a warning and force it to 11025 Hz by resampling up or down. warn emit a warning but include it as is anyway. accept silently include it as is. Previously, the default (and only option) used to be "force". It's now "warn". Thanks to Matthew W. Miller for telling me about this issue (which he did in 1999 ; the six-year delay is mine, all mine). * Sound: write errors while extracting PC speaker sounds are now actually detected and reported. DeuTex 4.4.0 (AYM 2000-01-05) * Game: Hexen: musics are now identified and extracted properly. The old music identification code assumed that any lump whose name does not begin with either "D_" or "MUS_" can't be a music. It worked for Doom, Heretic and Strife but, for Hexen, it caused all musics to be seen as plain lumps and extracted accordingly into the lumps/ directory. DeuTex even tried to interprete STALKR and WINNOWR as pictures and said silly things about them having a "width greater than 4096". The new code really checks whether the lump begins with "MUS\x1a" instead of just looking at its name. A lump is now deemed to be a music if and only if it begins with "MUS\x1a". As a side-effect, certain operations (appending sprites and flats and merging) must have become slower. Furthermore, since these used to blindly assume that any lump whose name begins with either "D_" or "MUS_" is a music, their semantics might have changed. If you find they don't do what you want, try again using the -musid option and let me know whether it improves your condition. * Game: Hexen, Doom alpha 0.4/0.5: levels are now properly extracted and included. There have been changes in the undocumented details of DeuTex's behaviour with respect to levels. The one that is most likely to be noticed is that, when including a level, DeuTex now copies the entire contents of the levels/ pwad, starting from the level label. Previously, it included at most the 11 following lumps, and only if they had the expected names (THINGS, VERTEXES and so on). But, basically, if the levels/ pwads contain, as they should, all the needed lumps and nothing else, there shouldn't be any trouble. * Game: Heretic and Hexen: does not abort anymore with "Bug: *** idinx (12) ***" when trying to include the graphic lumps (resp. CREDIT, E2END, FINAL1, FINAL2, HELP1, HELP2, TITLE and CREDIT, FINALE1, FINALE2, FINALE3, HELP1, HELP2, INTERPIC, TITLE). More generally, DeuTex now accepts to compose wads even when there are graphic files in lumps/. * Game: Hexen: does not abort anymore with "Height of FLAT ./flats/x_001.ppm is not 64 or 65" when trying to include flats X_001 through X_011. In addition, DeuTex now just emits a warning instead of aborting for other oddball heights (i.e. not 64, 65 or 128). Have fun. ;-) This is true for all iwads, not only Hexen. * Graphics: the annoying "quantisation is slow" warnings now appear at most once. * Misc: to disambiguate the " warnings omitted" message, added optional scope prefix and changed the picture extraction function to use it. * Misc: got rid of the "don't bother Olivier" banner. People must have got the message by now. DeuTex 4.3.0 (AYM 1999-12-24) * Graphics: fixed ancient bug where DeuTex sometimes failed to include custom patches if they were not explicitly listed in the [patches] section. If the first patch used in texture1.txt was a custom patch, it had to be listed in [patches] or DeuTex would forget to include it. This is the same bug Olivier mentioned in the home page : The support for wall patches in DeuTex has been modified. You must now explicitely declare all your patches in a [PATCHE] section. If you don't do this, DeuTex will attempt to work as usual, but there seems to ba a bug in this part of the code, so sometime some needed patches are not loaded. After some summary testing, looks like it's fixed. * Misc: more error handling improvements. * Misc: bumped version number and cleaned things up for public release. * Misc: decreased maximum number of warnings per picture from 10 to 5. * Platform: fixed ftruncate() being undeclared when compiling with DJGPP and updated the building-on-DOS section of the doc. DeuTex 4.2.2 (AYM 1999-11-20) (not for public consumption) * Misc: made certain failure messages more informative. * Platform: fixed several bugs that showed in the DOS precompiled executables for 4.1.0 and 4.2.0 (most common symptom : DeuTex aborting with a "Can't read WAD" error message). Lengthy technical explanation : in 4.1.0, I removed the "huge" pointer qualifiers that were scattered throughout the source not unlike nitrates in groundwater. The reasoning was that, since DeuTex is always compiled in the "huge" memory model anyway, those qualifiers were redundant. As I found out at the end of a long and painful debugging session, they weren't. Had I read the doc of the compiler, I would have known that, even when in the huge memory model, pointers are "far" by default, not "huge". Far pointers wrap around at 64 kB ; this is not what you want when you're trying to work with lumps larger than that. And, apparently, there is no way to specify that pointers should be huge by default. On top of that, there was a genuine bug in WADRreadBytes2() that would have prevented the DOS port from working, even if all pointers had been huge. But this one was fixed in 4.2.1. I switched to DJGPP, with which you can get working executables without having to contaminate your code with carcinogenic keywords. The bad news : firstly, the executables are somewhat larger. Secondly, since DJGPP executables use protected mode, they tend to be more fussy. Thanks to Kim Parrott for reporting the bug and alpha testing my fixes. All the above applies only to the DOS precompiled executables. Other platforms did not have these problems. DeuTex 4.2.1 (AYM 1999-11-16) (not for public consumption) * CLI: fixed segfault on "deutex --vers". * Graphics: new option -usedidx. When called with this option, DeuTex scans all the graphics in the wad and prints statistics about which palette indices they use. (By "graphics" is meant "any data that is converted into an RGB triplet by looking up PLAYPAL or TITLEPAL". That includes flats, graphics, patches, sneaps, sneats and sprites.) I've added this command for my own use, to help me decide which index should be used to store the transparent colour for Hexen. * Misc: made certain failure messages more informative. * Misc: made printing of lump names garbage-proof. * Platform: fixed a huge DOS bug that made DeuTex fail with a "Can't read WAD" error whenever it had to read more than 65535 bytes from a wad at once. * Platform: flushing stdout before writing to stderr so that messages come out in the right order when both outputs are redirected. * Sound: all conditions that used to be fatal errors when extracting sound lumps now just elicit a warning message, indicating which lump it was and what action was taken. DeuTex 4.2.0 (AYM 1999-11-14) * Doc: fixed error in documentation of -pkgfx, -pknormal and -usedtex. * Game: Strife: fixed DeuTex aborting when extracting textures for versions of Strife >= 1.1. The problem was that Strife 1.1 and above use a different format for the TEXTURE1 and TEXTURE2 lumps (Strife 1.0 uses the same format as Doom). New options "-tf strife11", "-itf strife11" and "-otf strife11" to support that format. Option -strife has been changed to imply "-tf strife11". New option -strife10 that is identical to -strife except that it does not imply "-tf strife11". Summary : * if you have the Strife 1.0 iwad, use "-strife10" (or "-tf normal"), * if you have Strife 1.1 or above, use "-strife" (or "-tf strife11"). Thanks to Kim Parrott for reporting the bug and Len Pitre for pointing me in the right direction. * Sound: fixed two bugs in reading Sun audio (.au) files. Fixes error "WAV: can't read data of./sounds/foo.au" (sic) when trying to build a wad. One of these bugs prevented from reading Sun audio files on little-endian machines. It had been there for a long time ; v3.8 has it and the v3.6 binary behaves like it had it too. I doubt that anyone had ever been able to use .au files on little-endian machines before. DeuTex 4.1.0 (AYM 1999-11-01) * CLI: new options -sneas, -sneaps and -sneats. * Code: removed all occurrences of "huge" on the theory that, on platforms where it's meaningful, we always use the huge memory model anyway. * Code: replaced certain occurrences of "Int32" by "iolen_t". * Code: replaced certain occurrences of "256" by "NCOLOURS". * Doom alpha 0.4: AMENA0 and MSKUL* are now correctly recognized as graphics and not as lumps anymore. The 21 graphic lumps that ended up in lumps/ are now properly extracted (into sneaps/ and sneats/). (The first item involved propagating to IDENTgraphic() the changes made to PICtoRAW() in v. 4.0.2. The second item needed heavy hacking, creating a new image type (christened "snea") and managing an alternate palette for TITLEPAL.) Still extracted as lumps : GNUM[0-9] and HUFONT. * Doom alpha 0.5: the 86 graphic lumps that ended up in lumps/ are now properly extracted (into sneaps/ and sneats/). Still extracted as lump : HUFONT. * Graphics: errors that used to cause DeuTex to give up on extracting a picture now just make it skip the rest of column. It also prints detailed messages about what it didn't like and in which picture it occurred instead of bailing out silently. * Misc: new option -di to debug entry identification. Useful mainly to hackers. * Misc: cosmetic changes in the generated wadinfo.txt and in the phase messages. * Misc: no more messages "Creating PWAD" and "WAD is complete..." during level extraction. * Misc: set a limit of 10 warnings per picture, to prevent invalid pictures from uselessly flooding the output. DeuTex 4.0.3 (AYM 1999-10-02) * CLI: new option -doom2 as suggested by Matthew Miller. * Graphics: now accepts to extract pictures as large as 4096 *4096 (previously the limit was 320 *200). This fixes "Failed to write sprite" errors when trying to extract PSYBA0 and PSYBB0 from strain.wad. Thanks to Matthew miller for reporting the bug. * Misc: added a useful URL to the GIF warning. * Platform: now builds without errors on FAT filesystems (replaced .deutex and .deusf by tmp/_deutex and tmp/_deusf). * Sound: fixed a bug that caused DeuTex to extract sounds with unlikely sample rates like 4 GHz whenever the sample rate in the lump was higher than 32767 Hz (for example DSVILACT and DSVILSIT from ncc1701.wad, with a sample rate of 44.1 kHz). Thanks to Matthew Miller for reporting the bug. DeuTex 4.0.2 (AYM 1999-09-19) * CLI: new options * -doom02 (implies -ipf alpha, -itf none and -itl none) * -doom04 (implies -ipf alpha, -itf nameless and -itl textures) * -doom05 (implies -ipf alpha and -itl textures) * -doompr (implies -ipf pr) Use those options where you would have used -doom and friends. For example, to extract the contents of the Doom 0.4 iwad that is in c:\doom0_4, type "deutex -doom04 c:\doom0_4 -xtract". * Code: replaced certain unjustified uses of Int32 by long. * Doc: removed old/readme.txt. It's so out of date that it's more confusing than useful. * Game: Doom alpha and Doom PR: it's now possible to extract graphics, patches, sprites and textures from those iwads. Three new options : -ipf {normal|pr|alpha} Use alpha for Doom alpha 0.2, 0.4 and 0.5. Use pr for Doom PR (press release pre-beta). Use normal for everything else. -itf {normal|nameless|none} Use none for Doom alpha 0.2. Use nameless for Doom alpha 0.4. Use normal for everything else, including Doom alpha 0.5. -itl {normal|textures|none} Use none for Doom alpha 0.2. Use textures for Doom alpha 0.4 and 0.5. Use normal for everything else, including Doom alpha 0.5. You shouldn't ever have to use those options directly. It's better to use just -doom02, -doom04, -doom05 and -doompr, which take care of setting ipf, itf and itl properly for you. Note that extracting levels and some other lumps from the Doom alpha iwads does not work yet. * Platform: new target in the makefile to generate a binary DOS distribution with the executables and the user documentation in DOS format, with DOS-ish names. DeuTex 4.0.1 (AYM 1999-09-10) * CLI: reworked the command line arguments parsing, with the following consequences. * Options can now be abbreviated freely, as long as the abbreviation is not ambiguous. For example, you can use -heretic, -hereti, -heret, -here or -her but not -he because that could also be the abbreviation for -help (or -hexen, for that matter). On the other hand, -h is allowed because it's not an abbreviation (there's really a -h option). * -heretic and -hexen now work (they were "hidden" by -h[elp]). * -v@ has been split in -v0, -v1 ... -v5 because the new code does not allow excess characters after an option. -vstring where string is anything else than "0" through "5" now triggers an error (it used to be accepted silently). I hope no one relied on the old undocumented behaviour. * Certain silly command line arguments that would have worked before would now trigger an error. For example, it used to be possible to type -extramarital or -extermination for -extract but not anymore. The old code defined relatively short options (-ext) and accepted command line arguments as long as the defined option was an initial substring of the command line argument. The new code does the reverse; it defines relatively long options (-extract) and accepts command line argument as long as they're an initial substring of the defined option. * Code: replaced direct testing of __MSDOS__, __OS2__, __GNUC__, __BORLANDC__ by DT_CC and DT_OS. This is hopefully going to make Udo's job a bit easier. * Code: now uses the same fopen() modes for all platforms: "{rw}b" for binary mode and "{rw}" for text mode, as per the ANSI/ISO C standard. This will fix the problem Udo Munk reported with the Cygwin build opening binary files in text mode and thus failing miserably. Note that certain DOS C compilers can be configured so that "{rw}" opens files in binary mode. Don't do that ! If you have problems with text files on DOS, make sure your C compiler is configured so that "{rw}" opens files in text mode. * Code: added to the distribution archive gifcodec.c that I had forgotten to include (it's not used anyway). * Code: added to the distribution archive src/{deusf,deusfos,deutex,deutexos}.def that I had forgotten to include. I guess that's Windows/OS/2-only stuff. * Doc: updated making.txt and renamed it as INSTALL for homogeneity. Removed obsolete reference to alpha.sh and the file itself. * Doc: made more legal updates. * Doc: documented DOOMWADDIR in the man page. * Misc: changed the default graphics format for Unix from GIF to PPM, so that fewer user sites are broken if and when GIF support is removed. For the same reason, added a warning message when -gif is used or the first time an image is read from a GIF file. * Misc: changed the lookup order for images to PPM, BMP, GIF (was BMP, GIF, PPM). * Platform: fixed a couple of things that didn't work on 16-bit platforms (real-mode DOS). * Platform: now compiles on DOS with Borland C++ 4.0. * Platform: now compiles on DOS with MSC 6.0. The MSC 6.0 build is functional but limited because it can't allocate blocks larger than 64 kB, which is insufficient for certain images. I can't use halloc() instead of malloc() because it does not supporting resizing (i.e. there's no hrealloc() function). * Platform: in response to Udo's remarks, DJGPP and Cygwin are now properly identified (__DJGPP__ and __CYGWIN__). * Platform: added sanity checks on specified-size types Int32 and friends. DeuTex 4.0.0a3 (AYM 1999-09-05) * Code: removed incongruous #define-ing of O_BINARY and SEEK_SET. * Code: after Udo Munk's report, fixed warnings in * src/color.c(74) * src/ident.c(583) * src/ident.c(658) * src/mkwad.c(78) * src/mkwad.c(79) * src/mkwad.c(80) * src/mkwad.c(81) * src/picture.c(903) * src/picture.c(912) * Doc: updated making.txt. * Legal: as agreed to by Olivier Montanuy, DeuTex is now entirely GPL'd. Well, almost entirely, since it includes code written by different authors in lzw.c and elsewhere. Changed the notices in the source files and added new file LICENSE to clarify things. * Makefile: should now work with all C compilers (removed -Wall from CFLAGS). * Makefile: clean now removes the DOS executables if they exist. * Makefile: does not compile with debug information in by default anymore. * Makefile: new targets dall, ddt, dds, ddeutex and ddeusf for compiling with debug information and all warnings. * Makefile: new target help. * Makefile: new target distdos. * Platform: replaced unlink() by remove() for portability. Thanks to Udo for reporting this. * Platform: on 8.3 filesystems, make should not choke on docsrc/changes.html anymore. Thanks to Udo for reporting this. * Sound: corrected some misleading endianness comments in sound.c. DeuTex 4.0.0a2 (AYM 1999-08-14) * Game: easier to use with Strife (now looks for "strife1.wad", new option "-strife"). * Game: easier to use with Hexen (new option "-hexen"). * Command line: new options "-hexen" and "-strife". * Command line: new option "--version" (prints version number and returns 0). * Doc: various changes in the man page, in the output of "-help" and "-man" and elsewhere. * Makefile: various improvements. * Distribution: set modes straight. DeuTex 4.0.0a1 (AYM 1999-08-12) * General: fixed many segfaults that were caused by attempts to fclose (NULL). * Game: Strife is now supported. * Wad: new options -be, -le, -ibe, -ile, -obe and -ole to control the endianness of the wads. Caution: don't use them if you don't know what you're doing ! As far as I know, wads are always little-endian regardless of the architecture of the host. Therefore, I see no reason for someone in his/her right mind to create a big-endian wad. Those options are here more for the sake of completeness than anything else. * Wad: made "%" legal in names, to deal with Strife's "INVFONG%" and "INVFONY%". * Wad, graphics: end-of-flats marker is now F_END by default instead of FF_END. The reason for this change is that, with F_END, you don't need DeuSF to get Doom to see your new flats. Should you need to, it's still possible to get FF_END by using -fend. * Graphics: the default transparent colour is now a dark blue-green (rgb:00/2f/2f). It used to be cyan (rgb:00/ff/ff) which was blindingly bright, especially compared to the usually dark colours used in Doom textures. It's no fun to tweak shades of dark brown on a cyan background. To reuse images done with/for a previous version of DeuTex, you need to either invoke DeuTex with "-rgb 0 255 255" or convert your images by replacing all occurrences of colour (0, 255, 255) by colour (0, 47, 47). To preserve compatibility with WinTex, I didn't change the default transparent colour in WinTex mode ; it's still (0, 255, 255). * Graphics: fixed segfaults due to bug in conversion of bitmap images to Doom pictures. Occured in certain 2-pixel high images such as STBFN045 in the Strife iwad. * Graphics: now supports pictures and textures up to 509 high (was limited to 128). * Graphics: now supports pictures and textures up to 1024 wide (was limited to 512). * Graphics: new option "-pf" to deal with the different picture format in the Doom alpha iwad (the underlying functionality is not implemented yet !) * Graphics: using -ppm does not cause anymore DeuTex to abort with "Bug: *** psvit ***". * Graphics: fixed "-ppm" message. * Sound, platform: a bug that must have prevented reading .wav files on big endian machines has been squashed. * Command line: options can't start with a slash ("/") anymore. I don't think anyone used it and was a silly feature for a Unix program. * Command line: not case insensitive anymore. * Command line: changed the wording of error messages to use "option" instead of "command". * Command line: added options "-?" and "--help" as synonyms for "-help". * Doc: new option "-man" to print help in troff -man source format for inclusion in the man page. * Doc: the version number is now a free-form string. * Doc: Made on-line help more compact. * Doc: updated "making.txt". * Doc: made a proper README file. * Makefile: renamed "unix" target as "strip". * Makefile: new target "install". * Makefile: new target "dist". * Platform: reworked the handling of endianness. DeuTex used to deal with that through a set of macros that swapped bytes whenever the required endianness was not the same as the native endianness. To known the native endianness, DeuTex relied on a macro defined via -D. There were two problems with this scheme. Firstly, Olivier got the meaning of "little endian" and "big endian" backwards and defining LITTLE_ENDIAN in fact caused DeuTex to believe it was being compiled for a big endian machine. As the glibc headers happen to define LITTLE_ENDIAN if the machine is little endian, compiling DeuTex on a glibc little endian Linux system was impossible unless you made changes to the source. The other, more fundamental, objection against the old approach is that, as it needed the user to tell it about the native endianness by modifying the makefile, it prevented unattended builds and made things difficult for naive users. The new method eliminates this problem by using a different algorithm that does not need to know the native endianness. The end result is that you don't have to worry about endianness anymore. * Internal: in TXTinit(), removed useless "% 0xFF" in index of TXTval. deutex-4.4.902/COPYING0000644000324500032450000004313510235470453013634 0ustar aymaym00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. deutex-4.4.902/COPYING.LIB0000664000324500032450000006131410304425016014232 0ustar aymaym00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! deutex-4.4.902/FAQ0000644000324500032450000000521310305357507013130 0ustar aymaym00000000000000THIS IS A GENERATED FILE -- DO NOT EDIT ! Edit docsrc/faq.html instead. DeuTex FAQ 1. When I extract the contents of the Heretic iwad, why are CREDIT, E2END, FINAL1, FINAL2, HELP1, HELP2 and TITLE extracted into lumps/ and not into graphics/ ? They're extracted into lumps/ because that's what they are. The graphics/ directory is for images that are in the in the so-called "picture" format, described in section [5-1] of the [1]UDS ([2]HTTP link). Those lumps are not in picture format, they're just straight bitmaps (320 * 200 pixels, 64,000 bytes). The distinction may seem academic, but it isn't. If those lumps were extracted into graphics/, it would be impossible to compose your wad correctly afterwards. In the wad created by DeuTex, CREDIT and friends would be in the picture format while the engine expects them to be in the 64000-byte matrix format. 2. When I extract the contents of the Hexen iwad, why are CREDIT, FINALE1, FINALE2, FINALE3, HELP1, HELP2, INTERPIC and TITLE extracted into lumps/ and not into graphics/ ? See question [3]1. 3. I've composed a wad. When I play it, the transparent areas in the graphics look opaque and blue or grey, like this : [4]Screenshot This is what happens when you try to use DeuTex 4 on files extracted by DeuTex 3 or WinTex. It happens because DeuTex 3 and WinTex use (0, 255, 255) (cyan) for transparent areas while DeuTex 4 uses (0, 47, 47) (dark blue-green). Therefore, what looks like a transparent pixel to DeuTex 3 and WinTex just looks like an opaque, cyan pixel to DeuTex 4. The closest match to cyan in the Doom palette is (115, 115, 255) (blue-mauve) so that's what you get. Try one of the following : * convert your files to use (0, 47, 47) instead of (0, 255, 255), * recreate your files using DeuTex 4, * recreate your files using DeuTex 3 with the "-rgb 0 47 47" option, * recreate your files using WinTex using the appropriate option (if it exists), * when composing, give DeuTex 4 the "-rgb 0 255 255" option. 4. The musics are extracted into lumps/. This has been fixed in version 4.4. 5. When composing, is there a way to include only the resources actually used by the levels ? No. Though it would certainly be nice to have. --------------------------------------------------------------------------- AYM 2005-08-29 References Visible links 1. ftp://archives.3dgamers.com/pub/idgames/docs/editing/dmspec16.zip 2. http://www.gamers.org/pub/idgames/docs/editing/dmspec16.zip 3. file:///aym/src/doom/deutex/docsrc/faq.html#q1 deutex-4.4.902/INSTALL0000644000324500032450000001350310305357507013630 0ustar aymaym00000000000000 DeuTex/DeuSf compilation by Olivier Montanuy Revised AYM 1999-08-12 Last update 2005-08-19 *********************** * Generic Unix-like * *********************** Type ./configure make make install # as root See near the end of the file for any OS-specific details. *************** * DOS * * Windows 95 * * Windows 98 * * Windows NT * *************** Borland C++ Turbo C++ Versions of DeuTex prior to 4.1.0 work fine when compiled with Borland C++ 4.0. DeuTex 4.1.0 and later can still be compiled with BC4 but the resulting executable is partially broken (does not handle correctly lumps larger than 64 kB). I believe it's the same for Borland/Turbo C 3.x and 2.x. The reason why it's broken is that, in v4.1.0, I've removed all "huge" qualifiers from the code, thinking that pointers were huge by default since DeuTex uses the huge memory model. I was wrong. I've been told that there is a version of Borland C for which, in the huge memory model, all data pointers are huge by default. If your version of BC has this feature, you should be able to use it to compile DeuTex. To compile, type dos\buildbc dir where dir is the directory where the compiler is installed, followed by a backslash (E.G. "dos\buildbc c:\bc4\"). Once deusf.exe and deutex.exe are built, copy them manually to a directory in your path. Don't try to use the makefile; due to idiosyncrasies in the CLI of bcc, limitations of Borland make and of the FAT filesystem, it won't work. There are old project files lying around in old/ but they've not been updated since 1995 so don't use them either. The compiler can be configured so that "{rw}" opens files in binary mode. Don't do that ! If you have problems with text files on DOS, make sure the compiler is configured so that "{rw}" opens files in _text_ mode (that's the default). Microsoft C As of version 4, DeuTex can be built with MSC 6.0. Other versions of MSC might work too, but have not been tried. To compile with MSC 5.1, you would have to remove the #error directives, since these are not supported in that version. Even though DeuTex compiles fine, the resulting executable is partially broken because it can't allocate blocks larger than 64 kB. To compile, type dos\buildmsc (that script assumes INCLUDE, LIB and PATH are properly set up). Once deusf.exe and deutex.exe are built, copy them manually to a directory in your path. The compiler can be configured so that "{rw}" opens files in binary mode. Don't do that ! If you have problems with text files on DOS, make sure the compiler is configured so that "{rw}" opens files in _text_ mode (that's the default). DJGPP 2.* Thanks to Udo Munk, DeuTex can now be built with DJGPP. You need a command named "cc" in your path, that points to "gcc.exe" (just type "copy c:\djgpp\bin\gcc.exe c:\djgpp\bin\cc.exe"). The makefile recipes are written for Bourne-compatible shells like bash. If your DJGPP installation is set up so that make executes the recipes with an incompatible shell such as command.com, it won't work. Make sure you have Bash or some other Bourne-compatible shell installed and, if necessary, invoke make with the SHELL variable set to the pathname of that shell ("make SHELL=c:\foo\bash.exe") Some recipes also require Unix commands like cp, mv, rm, touch etc. so you may have to install additional packages. If you're feeling lucky, type dos\builddj After deusf.exe and deutex.exe are created, copy them to a directory in your path. Cygwin Thanks to Udo Munk, DeuTex can now be built with Cygwin. I've not tried it myself, but it should be pretty much like compiling on any Unix : ./configure make make install *************** * Windoze 3.1 * *************** by Olivier Montanuy Use the DOS deutex version under windows, with a suitable deutex.pif .DLL DeuTex itself can't be compiled as a 16-bit windoze DLL (too big). The lbdeutex is for the visual basic shell. ************** * OS/2 2 2.1 * ************** Borland C++ Turbo C++ Might work. See the corresponding paragraphs in the DOS section. Microsoft C Might work. See the corresponding paragraphs in the DOS section. IBM C Set++ 2.1 (by mark+mathews=channel1+com) For DEUTEXOS.EXE you need deutexos.mak and deutexos.def To make DEUTEXOS.EXE type: nmake -f deutexos.mak For DEUSFOS.EXE you need deusfos.mak and deusfos.def To make DEUSFOS.EXE type : nmake -f deusfos.mak AYM 1999-08-12: Where are deutexos.mak and deusfos.mak ? Better use the main makefile anyway... ************************ * Porting DeuTex/DeuSF * ************************ The name of the OS DeuTex is being compiled for is in DT_OS, defined in deutex.h : #define DT_OS 'd' /* MS-DOS */ #define DT_OS 'o' /* OS/2 */ #define DT_OS 'u' /* Unix (in fact, anything else) */ The name of the compiler is in DT_CC, defined in deutex.h : #define DT_CC 'b' /* Borland C */ #define DT_CC 'c' /* GCC/EGCS with Cygwin */ #define DT_CC 'd' /* DJGPP */ #define DT_CC 'g' /* GCC/EGCS */ #define DT_CC 'i' /* IBM C Set++ */ #define DT_CC 'm' /* Microsoft C */ #define DT_CC '?' /* Unknown compiler */ Testing the existence of other macros, such as __MSDOS__, __GNUC__ etc. is discouraged. Use DT_OS and DT_CC instead. Some structures related to pictures or to DOOM assume that no word or long word alignement occur. If the fields are not contiguous in core, DeuTex and DeuSF will not work, but there will be no warning. Most of the O/S related functions are in tools.c. deutex-4.4.902/LICENCE0000644000324500032450000000613310305357507013565 0ustar aymaym00000000000000 Licence terms for DeuTex ------------------------------------------------------------------------ DeuTex is Copyright © 1994-1995 Olivier Montanuy, and Copyright © 1999-2005 André Majorel. The parts of DeuTex that have been written by Olivier Montanuy, Kevin McGrail, André Majorel and other contributors are distributed under the terms of version 2 of the GNU general public license (GPL). 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 Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------ However, the DeuTex distribution includes material that was written by other people or distributed under different licences : 1. DeuTex incorporates code derived from DEU 5.21. DEU 5.21 was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. No part of DeuTex is public-domain, however. 2. The file gifcodec.c is Copyright © 1995 David Kaplan. 3. The file lzw.c contains the following notes : > Copyright 1993, David Koblas (koblas=netcom+com) > > Permission to use, copy, modify, and to distribute this software > and its documentation for any purpose is hereby granted without > fee, provided that the above copyright notice appear in all > copies and that both that copyright notice and this permission > notice appear in supporting documentation. There is no > representations about the suitability of this software for > any purpose. this software is provided "as is" without express > or implied warranty. > This file is derived from ppmtogif.c and giftoppm.c > only the compression/decompression routines were kept. > > Based on GIFENCOD by David Rowley . > A Lempel-Zim compression based on "compress". > > Copyright (C) 1989 by Jef Poskanzer. > > Permission to use, copy, modify, and distribute this software and > its documentation for any purpose and without fee is hereby > granted, provided that the above copyright notice appear in all > copies and that both that copyright notice and this permission > notice appear in supporting documentation. This software is > provided "as is" without express or implied warranty. > > The Graphics Interchange Format(c) is the Copyright property of > CompuServe Incorporated. GIF(sm) is a Service Mark property of > CompuServe Incorporated. 4. The files endianio.c and endianm.c are Copyright © André Majorel 1999 and available under the terms of the LGPL. -- AYM 2005-08-28 deutex-4.4.902/README0000644000324500032450000000352310305357507013460 0ustar aymaym00000000000000DeuTex 4.4.902 DESCRIPTION DeuTex and DeuSF are programs than can do many things with Doom, Heretic, Hexen and Strife wad files such as extracting and inserting graphics, sounds, levels and other resources. See the manual for details (dtexman6.txt). BUILDING AND INSTALLING ON UNIX You need a reasonably standard Unix environment with a C compiler. The first step is to type ./configure If you need to install somewhere else than /usr/local, give ./configure the --prefix option. For example, to install in ~/deutex, ./configure --prefix ~/deutex The C compiler is auto-detected. If the auto-detection does not find your compiler, use the --cc option : ./configure --cc ~/mycc-1.2.3/mycc The default CFLAGS is "-O2 -Wall" for GCC, "-O" for other compilers. The default LDFLAGS is empty. To override these, you can use the --cflags and/or the --ldflags options. For example, ./configure --cflags '-O2 -m64' --ldflags '-m64' After ./configure completes successfully, type make Finally, type make install Note that you will need to type this last command as root if you're installing in /usr/local or some other "system" directory. BUILDING AND INSTALLING ON DOS See INSTALL. LEGAL DeuTex is Copyright Olivier Montanuy 1994-1995 and Copyright André Majorel 1999-2005 and available under the terms of version 2 of the GPL, except lzw.c which is Copyright David Koblas and others and available under the terms of the PBMPLUS license. See the LICENSE file. All trademarks are the property of their owners. CONTACT Home page : http://www.teaser.fr/~amajorel/deutex/ Doom questions : news:rec.games.computer.doom.editing DeuTex questions : The Yadex mailing list (http://www.teaser.fr/~amajorel/yadex/lists.html) -- AYM 2005-08-19 deutex-4.4.902/TODO0000644000324500032450000002700710305357510013265 0ustar aymaym00000000000000THIS IS A GENERATED FILE -- DO NOT EDIT ! Edit docsrc/todo.html instead. To-do list for DeuTex Directives file * In the directives file and textures files, "include" directive to include the rest of another block/file. * In the directives file and textures files, allow references to environment variables (E.G. $E(name)). * In the directives file and textures files, allow user variables (E.G. $(name)) * Make it easier to let a texture have a description identical to another texture * In the directives file, add a mean to import all/only named/all except named flats as patches. * In the directives file, add a mean to import all/only named/all except named patches as flats. This implies 1) accepting flats larger than 64 *64 (by clipping) 2) converting transparent pixels to a certain colour (which one ?). * In the directives file, add a mean to automatically generate a texture for all/only named/all except named patches. The height of the automatic texture is 128, its width is the least power of two wide enough to contain the patch. The automatic texture is filled with the patch by tiling, starting from the top left corner. The name of the automatic texture is the name of the patch. * Wherever an image is imported, give the option of applying graphical transforms: crop, tile, rotate, mirror, roll, colour. * Wherever an image is imported, give the option of composing the image from several files. This would be particularly useful for flats, which cannot be composed from several patches like textures do. This might complicate the wadinfo.txt syntax, though. * Instead of allowing any and all characters in the script file, require them to be quoted. And, when doing -xtract, produce the script file with the appropriate quotes... Since, under Unix, the only characters that are not allowed in a file name are NUL and "/", I don't see why DeuTex should prevent users from extracting lumps with weird characters in their names. However, that might cause compatilibity problems with the DOS version. * When composing, warn about invalid sections (E.G. "[poo]"). Game support * Doom alpha GNUM[0-9] : * find name for 10x12, preferably ending in "p" (xxx), * implement IDENTxxx(), * add [xxx] section to wadinfo.txt, * make list of lumps that used to go in lumps/ and now go in xxx/ and put that in changes.html, * create corresponding -sprites-like option * When extracting the Doom alpha 0.2 iwad, "Can't find PNAMES in wad". * Doom alpha 0.4 and 0.5: MENUMAP is not supported. * DeuTex should not look for doom.wad in the directory set by -heretic ! * Heretic: E2END is extracted with the wrong palette. * Hexen: does not extract graphics quite correctly (applies transparent colour translation to opaque images such as FINALE1 and FINALE2). This is probably related to [1]. * Strife: compile scripts. * Strife: what else is missing ? * ROTT: add -rott and remove the ROTT macro. * ROTT: use AP_PAL instead of PAL for the Apogee thing. * ROTT: work on the identification (ANIMSTRT, EXITSTRT, EXITSTOP, ABVWSTART, ABVMSTRT, HMSKSTRT, GUNSTART, ELEVSTRT/ELEVSTOP, DOORSTRT/DOORSTOP, SIDESTRT/SIDESTOP, MASKSTRT/MASKSTOP, UPDNSTRT/UPDNSTOP, SKYSTART/SKYSTOP, SKYSTART/SKYSTOP, ORDRSTRT/ORDRSTOP, ORDRSTRT/ORDRSTOP, SPECMAPS, PLAYMAPS SHAPSTRT/SHAPSTOP, DIGISTRT/DIGISTOP, SONGSTRT, PCSTRT/PCSTOP, ADSTRT/ADSTOP). * ROTT: seems to implement lump aliases by pointing to the same offset as an other lump. All lumps but the last have a zero size. Graphics * The presence of the GIF routines might push DeuTex into the non-free section of Debian. Would it be sufficient to #ifdef them out ? * Determine why converting Doom graphics to PPM and back does not yield the same thing. This also happens with BMP but much less so. Update 2000-01-04 : for example, with Heretic, patch WALL17 has its (4Eh, 50h, 4Dh) pixels turned into (4Eh, 4Eh, 4Eh). It seems DeuTex sometimes uses a close match even when an exact match exists. PPM and GIF do not agree with each other. An extract/build round trip on the Ultimate Doom iwad does not produce the same wad on DOS as it does on Unix because the default format on DOS is GIF. If you extract with -ppm on DOS, you do get the same wad you do on Unix. * Bug: some flats seem to be extracted with certain pixels set to the transparent colour (Doom's CEIL4_1). DeuTex 3.6 for DOS exhibits the same problem [1]. * Building seems to be slower than extracting. Perhaps RAWtoPIC() could use some optimization. * Include the Gimp and PSP palettes in the distribution. * For people who have old graphics files generated by DeuTex 3 with cyan (0, 255, 255) as the transparent colour : it would be nice if DeuTex 4 could import those files automatically. The way I see it, if no transparent pixel has been found in an image so far and if a cyan pixel is found, a warning is emitted ("Warning: xxxxxxxx.xxx: assuming the transparent colour is cyan.") and the transparent colour for this image is set to cyan. This would make for a smooth transition from DeuTex 3 to DeuTex 4. There should be a command-line switch to disable that feature. * Sneas are supported when doing -xtract but not when doing -build (they're ignored). Fix that, or at least mention it somewhere. Though I don't see many people wanting to make wads for Doom alpha anyway... Sound * Regarding audio support, Matthew W. Miller offered the following comment on 1999-07-04 : Audio handling in deutex (I'm referring to the irix 5.3 version's included source code) is, I believe, based on dmgraph, but is pretty dire in any case. [...] Also, one would hope that eventually one or more of the source ports will start to support bitrates other than 8 bit, and (maybe?) stereo samples. You may want to start leaning on various source ports' programmers to get their acts together and start coming to some sort of agreement. ;) Importation of .wav files is pretty crufty. Like dmgraph before it, the deutex 5.3 source expects there to be just one big 'data' chunk, and doesn't notice the 'info' chunks that certain stupid Windows programs (*cough*cough*CoolEdit*GoldWave*cough*) insist on putting in (usually with copyright messages for the program itself, which in a just world would be illegal). Greater explanation of all this whacky chunk business can be found at: [1]http://www.compsoc.man.ac.uk/~maniac/resource_web/wav_file_format/ (wav1.htm, wav2.htm, wav3.htm, 4.htm, 5.htm) Essentially, you want to clip out the first 'data' chunk and ignore crap like 'info', 'inam', 'list', or whatever. * Fix this : atc4:/doom/dev/test/wav/16$ deutex -doom /doom/doom -xtract ../16bit44k.wad DeuTex 4.0.3 Main directory: /doom/doom. Extracting entries from WAD ../16bit44k.wad Reading WAD /doom/doom/doom.wad: (2306 entries) Reading WAD ../16bit44k.wad: (1 entries) PWAD entry identification...done Color palette is Doom Warning: ** Appending to file ./wadinfo.txt ** Extracting Levels... Extracting Lumps... Extracting Sounds... Bug: *** not a WAVE *** Please report that bug. * Look into importing sounds as .wav's. What are the highest supported sample rates and resolution ? Seems to depend on the engine. Command line * The command line interface is not always intuitive and it's fussy about the position of certain options. -iwad seems to be ineffective if placed last. -xtract and friends must be placed last if they don't have all their arguments. * Options shouldn't care whether there is space between them and their argument. Hmm... or should they ? * -check shouldn't require an argument. It should use the iwad by default. * -main should be implemented for DeuTex as well. * Matthew Miller wants to be able to specify the name of the iwad instead of just its path (this is how it should have been done from the start, IMHO). Possible ways to do that : * stat() the argument to -doom, -heretic, etc. If it's a file and not a directory, use that. * Look for a different basename in the iwad directory, depending on the option through which the directory was specified. E.G. if it was set with -doom2, look for doom2.wad first. And if doom2.wad was not found, emit a warning. -doom and -heretic should look for all basenames because that's what previous versions of DeuTex did. * Add an option to specify the name of the iwad file, without specifying which iwad it is and let DeuTex guess what needs to be guessed. Apparently, there's already such an option (-main) but it's for DeuSF only. Why ? * Add -V (equivalent to --version). Include the URL of the original distribution archive ? Documentation * It's in shambles. * Mention that negative patch Y-offsets are forced to 0 by the engine. * Mention that sneaps are extracted but not built. * Man page: mention that some options are DeuTex-only, not DeuSF. * Document the messages. What I have in mind : $(msg AB34 w "Sneeze %{name}s: %{num}f dB > 100 dB, bad for straw huts" $("fname (pathname)" "strerror (errno)") $ ) which expands to : Warning("Sneeze %s: %f dB > 100 dB, bad for straw huts", fname (pathname), strerror (errno)); and : .TP \fBAB34 Sneeze \fIname\fB: \fInum\fB dB > 100 dB, bad for straw huts\fR Sneeze \fIname\fP is louder than 100 dB. Versions of House lesser than Wood will collapse. Platform * Borland C: to revive the port, must find a way to make all pointers implicitly huge. Misc. * TBD: New options -fstart and -fend to control the start-of-flats and end-of-flats markers used in pwads. Default to FF_START and F_END respectively. Warning: here again, don't use those options just because they're here. The default markers are perfectly fine, and they conform to the de-facto standard. If you deviate from them, you're asking for trouble. * -f_end * Why does "deutex -ipf alpha -doom .. -sprites -graphics -patches -xtract" trigger "Error: *** Can't open file ./lumps/titlepic.lmp ***" ? * todo.html grows faster than changes.html. Fix that. ;-) * -usedidx: don't count sneats (-nosneats ?). * The dependencies on deutex.h are missing in the makefile. * Integrate AJA's patch compression patch. * Change text file line numbers from shorts to longs. * If you -xtract doom.wad twice then build, you get either a PA90 bug or a wad that's twice as big as the original. * PrintInit() is called way too late. All error messages relative to parsing the command line will be written to standard error, not the specified file (asFile). Options that set asFile should be honour in the first pass. * The fact that Info(), Detail() and Phase() write to standard output is wrong if you take the stance that the real distinction between stdout and stderr is not information vs. error but "data to be processed by the next filter in the pipe" vs. "messages to be read by a human". If so, need to check that all uses of Output() are indeed "pipeable". Also, is it right to copy Output() to the log ? References Visible links 1. http://www.compsoc.man.ac.uk/~maniac/resource_web/wav_file_format/ deutex-4.4.902/deutex.60000644000324500032450000003402410305372574014166 0ustar aymaym00000000000000.\" This file is part of DeuTex. .\" .\" DeuTex incorporates code derived from DEU 5.21 that was put in the .\" public domain in 1994 by Raphaël Quinet and Brendon Wyber. .\" .\" DeuTex is Copyright © 1994-1995 Olivier Montanuy, .\" Copyright © 1999-2005 André Majorel. .\" .\" 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 library; if not, write to the Free Software Foundation, Inc., .\" 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. .\" .TH DEUTEX 6 2005-08-31 "DeuTex 4.4.902" .SH NAME deutex, deusf \- do things with wad files .SH SYNOPSIS .BR "deutex \-?" | \-h | \-help | \-\-help .br .B deutex \-\-version .br .B deutex \-man .br \fBdeutex\fP [\fIoptions\fP] .B \-add .I incomplete.wad out.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-af .I flats.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-append .I incomplete.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-as .I sprite.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-check .I in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-debug .RI [ in.gif ] .br \fBdeutex\fP [\fIoptions\fP] .B \-get .I entry .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-join .I incomplete.wad in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-make \fR[\fP\fIdirctivs.txt\fP\fR] \fP\fIout.wad\fP .br \fBdeutex\fP [\fIoptions\fP] .B \-merge .I in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-pkgfx .RI [ in.wad " [" out.txt ]] .br \fBdeutex\fP [\fIoptions\fP] .B \-pknormal .RI [ in.wad " [" out.txt ]] .br \fBdeutex\fP [\fIoptions\fP] .B \-restor\fP .br \fBdeutex\fP [\fIoptions\fP] .B \-usedidx .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-usedtex .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-unused .I in.wad .br \fBdeutex\fP [\fIoptions\fP] .B \-wadir .RI [ in.wad ] .br \fBdeutex\fP [\fIoptions\fP] .B \-xtract .I in.wad .RI [ dirctivs.txt ] .br .BR "deusf \-?" | \-h | \-help | \-\-help .br .B deusf \-\-version .br .BI "deusf " options .br .SH DESCRIPTION DeuTex is a wad composer for Doom, Heretic, Hexen and Strife. It can be used to extract the lumps of a wad and save them as individual files or the reverse, and much more. .PP When extracting a lump to a file, it does not just copy the raw data, it converts it to an appropriate format (such as PPM for graphics, Sun audio for samples, etc.). Conversely, when it reads files for inclusion in pwads, it does the necessary conversions (for example, from PPM to Doom picture format). .PP DeuSF is a trimmed version of DeuTex that is used to merge sprites and flats from a pwad into an iwad, which is sometimes necessary because Doom and its breed do not handle sprites in pwads well. .PP See \fBdocsrc/dtexman6.txt\fP for more information on DeuTex and DeuSF. .SS Decomposing a wad To decompose a wad (i.e. extract its contents), use the \fB\-extract\fP (a.k.a. \fB\-xtract\fP) command. When decomposing a wad, DeuTex creates one file for each lump. The files are created in one of the following subdirectories of the working directory: \fBflats/\fP, \fBlumps/\fP, \fBmusics/\fP, \fBpatches/\fP, \fBsounds/\fP, \fBsprites/\fP, \fBtextures/\fP. The decomposing process also creates a very important file, \fBwadinfo.txt\fP, which will be used later when composing. .PP To extract the contents of the Doom II iwad, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-xtract\fP .fi .PP To extract the contents of a Doom II pwad named \fImywad.wad\fP, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-xtract mywad.wad\fP .fi .PP To extract only the sprites, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-sprites \-xtract\fP .fi .PP To extract only the sounds and save them as .voc, .nf \fBdeutex \-doom2 /path/to/doom2.wad \-sounds \-voc \-xtract\fP .fi .SS Composing (building) a wad Composing is the symmetrical process. It's done with the three commands \fB\-build\fP, \fB\-create\fP and \fB\-make\fP, that are equivalent. Using \fBwadinfo.txt\fP and the files in flats/, lumps/, musics/, patches/, sounds/, sprites/ and textures/, DeuTex creates a new wad. .PP To create a new pwad named \fImywad.wad\fP, .nf .RS \fBdeutex \-doom2 /path/to/doom2.wad \-make mywad.wad\fP .RE .fi .PP To create a new iwad named \fImytc.wad\fP, .nf .RS \fBdeutex \-doom2 /path/to/doom2.wad \-iwad \-make mytc.wad\fP .RE .fi .SS Other operations DeuTex has many (too many ?) other commands like \fB\-join\fP, \fB\-merge\fP, \fB\-usedtex\fP etc. See \fBdocsrc/dtexman6.txt\fP for a full description. .SH OPTIONS .SS Modal options not requiring an iwad .TP \fB\-?\fP Same as \fB\-\-help\fP. .TP \fB\-h\fP Same as \fB\-\-help\fP. .TP \fB\-help\fP Same as \fB\-\-help\fP. .TP \fB\--help\fP Print list of options. .TP \fB\-man\fP Print list of options in troff \-man format. .TP \fB\-syntax\fP Print the syntax of wad creation directives. .TP \fB\-unused \fP\fIin.wad\fP Find unused spaces in a wad. .TP \fB\--version\fP Print version number and exit successfully. .SS Modal options requiring an iwad .TP \fB\-add \fP\fIin.wad out.wad\fP Copy sp & fl of iwad and \fIin.wad\fP to \fIout.wad\fP. .TP \fB\-af \fP\fIflats.wad\fP Append all floors/ceilings to the wad. .TP \fB\-append \fP\fIio.wad\fP Add sprites & flats of iwad to \fIio.wad\fP. .TP \fB\-as \fP\fIsprite.wad\fP Append all sprites to the wad. .TP \fB\-build \fP\fR[\fP\fIin.txt\fP\fR] \fP\fIout.wad\fP Make a pwad. .TP \fB\-check \fP\fIin.wad\fP Check the textures. .TP \fB\-create \fP\fR[\fP\fIin.txt\fP\fR] \fP\fIout.wad\fP Same as \fB\-build\fP. .TP \fB\-debug \fP\fR[\fP\fIfile\fP\fR]\fP Debug colour conversion. .TP \fB\-extract \fP\fR[\fP\fIin.wad \fP\fR[\fP\fIout.txt\fP\fR]]\fP Same as \fB\-xtract\fP. .TP \fB\-get \fP\fIentry \fP\fR[\fP\fIin.wad\fP\fR]\fP Get a wad entry from main wad or \fIin.wad\fP. .TP \fB\-join \fP\fIincomplete.wad in.wad\fP Append sprites & flats of Doom to a pwad. .TP \fB\-make \fP\fR[\fP\fIin.txt\fP\fR] \fP\fIout.wad\fP Same as \fB\-build\fP. .TP \fB\-merge \fP\fIin.wad\fP Merge doom.wad and a pwad. .TP \fB\-pkgfx \fP\fR[\fP\fIin.wad \fP\fR[\fP\fIout.txt\fP\fR]]\fP Detect identical graphics. .TP \fB\-pknormal \fP\fR[\fP\fIin.wad \fP\fR[\fP\fIout.txt\fP\fR]]\fP Detect identical normal. .TP \fB\-restore\fP Restore doom.wad and the pwad. .TP \fB\-test \fP\fIin.wad\fP Same as \fB\-check\fP. .TP \fB\-usedidx \fP\fR[\fP\fIin.wad\fP\fR]\fP Colour index usage statistics. .TP \fB\-usedtex \fP\fR[\fP\fIin.wad\fP\fR]\fP List textures used in all levels. .TP \fB\-wadir \fP\fR[\fP\fIin.wad\fP\fR]\fP List and identify entries in a wad. .TP \fB\-xtract \fP\fR[\fP\fIin.wad \fP\fR[\fP\fIout.txt\fP\fR]]\fP Extract some/all entries from a wad. .SS General options .TP 12 \fB\-overwrite\fP Overwrite all. .TP 12 \fB\-dir \fP\fIdir\fP Extraction directory (default \fB.\fP). .SS Iwad .TP 15 \fB\-doom \fP\fIdir\fP Path to Doom iwad. .TP 15 \fB\-doom2 \fP\fIdir\fP Path to Doom II iwad. .TP 15 \fB\-doom02 \fP\fIdir\fP Path to Doom alpha 0.2 iwad. .TP 15 \fB\-doom04 \fP\fIdir\fP Path to Doom alpha 0.4 iwad. .TP 15 \fB\-doom05 \fP\fIdir\fP Path to Doom alpha 0.5 iwad. .TP 15 \fB\-doompr \fP\fIdir\fP Path to Doom PR pre\-beta iwad. .TP 15 \fB\-heretic \fP\fIdir\fP Path to Heretic iwad. .TP 15 \fB\-hexen \fP\fIdir\fP Path to Hexen iwad. .TP 15 \fB\-strife \fP\fIdir\fP Path to Strife iwad. .TP 15 \fB\-strife10 \fP\fIdir\fP Path to Strife 1.0 iwad. .SS Wad options .TP \fB\-be\fP Assume all wads are big endian (default LE). .TP \fB\-deu\fP Add 64k of junk for DEU 5.21 compatibility. .TP \fB\-george\fP Same as \fB\-s_end\fP. .TP \fB\-ibe\fP Input wads are big endian (default LE). .TP \fB\-ile\fP Input wads are little endian (default). .TP \fB\-ipf \fP\fIcode\fP Picture format (\fBalpha\fP, *\fBnormal\fP, \fBpr\fP, \fBrott\fP). .TP \fB\-itf \fP\fIcode\fP Input texture format (\fBnameless\fP, \fBnone\fP, *\fBnormal\fP, \fBstrife11\fP). .TP \fB\-itl \fP\fIcode\fP Texture lump (\fBnone\fP, *\fBnormal\fP, \fBtextures\fP). .TP \fB\-iwad\fP Compose iwad, not pwad. .TP \fB\-le\fP Assume all wads are little endian (default). .TP \fB\-musid\fP Use old music identification method. .TP \fB\-obe\fP Create big endian wads (default LE). .TP \fB\-ole\fP Create little endian wads (default). .TP \fB\-otf \fP\fIcode\fP Output texture format (\fBnameless\fP, \fBnone\fP, *\fBnormal\fP, \fBstrife11\fP). .TP \fB\-s_end\fP Use \fBS_END\fP for sprites, not \fBSS_END\fP. .TP \fB\-tf \fP\fIcode\fP Texture format (\fBnameless\fP, \fBnone\fP, *\fBnormal\fP, \fBstrife11\fP). .SS Lump selection .TP 11 \fB\-flats\fP Select flats. .TP 11 \fB\-graphics\fP Select graphics. .TP 11 \fB\-levels\fP Select levels. .TP 11 \fB\-lumps\fP Select lumps. .TP 11 \fB\-musics\fP Select musics. .TP 11 \fB\-patches\fP Select patches. .TP 11 \fB\-scripts\fP Select Strife scripts. .TP 11 \fB\-sneas\fP Select sneas (sneaps and sneats). .TP 11 \fB\-sneaps\fP Select sneaps. .TP 11 \fB\-sneats\fP Select sneats. .TP 11 \fB\-sounds\fP Select sounds. .TP 11 \fB\-sprites\fP Select sprites. .TP 11 \fB\-textures\fP Select textures. .SS Graphics .TP \fB\-bmp\fP Save pictures as BMP (\fB.bmp\fP). .TP \fB\-gif\fP Save pictures as GIF (\fB.gif\fP). .TP \fB\-ppm\fP Save pictures as rawbits PPM (P6, \fB.ppm\fP). .TP \fB\-rgb \fP\fIr g b\fP Specify the transparent colour (default 0 47 47). .SS Sound .TP \fB\-au\fP Save sounds as Sun audio (\fB.au\fP). .TP \fB\-fullsnd\fP Save sounds beyond declared length. .TP \fB\-rate \fP\fIcode\fP Policy for != 11025 Hz (\fBreject\fP, \fBforce\fP, *\fBwarn\fP, \fBaccept\fP). .TP \fB\-voc\fP Save sounds as voc (\fB.voc\fP). .TP \fB\-wav\fP Save sounds as WAVE (\fB.wav\fP). .SS Reporting .TP 11 \fB\-di \fP\fIname\fP Debug identification of entry. .TP 11 \fB\-log \fP\fIfile\fP Name of log file (default \fBdeutex.log\fP). .TP 11 \fB\-v0\fP Set verbosity level to 0. .TP 11 \fB\-v1\fP Set verbosity level to 1. .TP 11 \fB\-v2\fP Set verbosity level to 2 (default). .TP 11 \fB\-v3\fP Set verbosity level to 3. .TP 11 \fB\-v4\fP Set verbosity level to 4. .TP 11 \fB\-v5\fP Set verbosity level to 5. .SS WinTex-related options .TP \fB\-win \fP\fIdoom data info select colour\fP WinTex shortcut. .TP \fB\-wim \fP\fIdoom select\fP WinTex shortcut. .TP \fB\-wtx \fP\fIiwad\fP WinTex shortcut. .SH DIAGNOSTICS All messages are identified by a unique code. Some messages are identical\ ; the code is useful to distinguish them. All codes have four characters\ ; two letters and two digits. The letters identify the part of the code where the message comes from, the digits give the message number within that area. In general, numbers are assigned so that messages that come from parts of the code that are executed earlier have lower numbers. .SH FILES .TP .IB dir /flats/ When extracting, flats are saved to this directory. When composing, flats are read from this directory. .TP .IB dir /graphics/ When extracting, graphics are saved to this directory. When composing, graphics are read from this directory. .TP .IB dir /levels/ When extracting, levels are saved to this directory. When composing, levels are read from this directory. .TP .IB dir /lumps/ When extracting, lumps are saved to this directory. When composing, lumps are read from this directory. .TP .IB dir /musics/ When extracting, musics are saved to this directory. When composing, musics are read from this directory. .TP .IB dir /patches/ When extracting, patches are saved to this directory. When composing, patches are read from this directory. .TP .IB dir /scripts/ When extracting, Strife scripts are saved to this directory. When composing, Strife scripts are read from this directory. .TP .IB dir /sneaps/ When extracting, Doom alpha sneaps are saved to this directory. When composing, Doom alpha sneaps are read from this directory. .TP .IB dir /sneats/ When extracting, Doom alpha sneats are saved to this directory. When composing, Doom alpha sneats are read from this directory. .TP .IB dir /sounds/ When extracting, sounds are saved to this directory. When composing, sounds are read from this directory. .TP .IB dir /sprites/ When extracting, sprites are saved to this directory. When composing, sprites are read from this directory. .TP .IB dir /textures/texture1.txt The \fBTEXTURE1\fP lump (all but Doom alpha 0.4 and 0.5). .TP .IB dir /textures/texture2.txt The \fBTEXTURE2\fP lump (all commercial iwads except Doom 2). .TP .IB dir /textures/textures.txt The \fBTEXTURES\fP lump (Doom alpha 0.4 and 0.5). .TP .IB dir /wadinfo.txt The default master file. .SH ENVIRONMENT .TP .B DOOMWADDIR The directory where the iwad resides. The value of this environment variable is overridden by \fB\-main\fP, \fB\-doom\fP and friends. .SH BUGS See \fBTODO\fP. .SH LEGAL DeuTex is copyright © 1994-1995 Olivier Montanuy, copyright © 1999-2005 André Majorel. .PP Most of this program is GPL'd but some of it is available under other licenses. 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 LICENSE for specific information and copyright notices. All trademarks are the property of their owners. .SH AUTHOR The original author of DeuTex is Olivier Montanuy . From 1994 to 1996, DeuTex was maintained by Olivier Montanuy with help from Per Allansson , James Bonfield , Sharon Bowles, Mark Mathews and Chuck Rossi. The original manual was written by Kevin McGrail . .PP As of version 4 (1999), the maintainer is André Majorel . .PP Questions and bug reports should be sent to the current maintainer, \fInot\fP to the original authors. .SH SEE ALSO .BR wadcat (6), .BR wadext (6), .BR wadext2 (6), .BR wadflat (6), .BR wadgc (6), .BR wadlc (6), .BR wadldc (6), .BR wadpatch (6), .BR wadsprit (6), .BR wadtex (6), .BR wadtxls (6), .BR xwadtools (6) deutex-4.4.902/dtexman6.txt0000664000324500032450000045774110304705364015105 0ustar aymaym00000000000000 ____________ __________________________ \ \ \ / / | _______ \ \_______ ________/ / | |\_____\ \ \______\ / \______\/ | | | | |\ | | / | | | | || __________ ____ ____ | | | __________ _____ ____ | | | | || \ _____/ / \ / \ \ / \ | | | \ _____/ /| \ / \ / \ | | | | || | |\___\/ | |/ | |/ | | | | |\___\/ \ \ \ / / / | | | _/ || | |_|____ | || | || | | | | |_|___ \ \ \/ / / | | |_/ __/ | | ____/ / | || | || | | | | ___/ / \/ \/ | |/ __/ __/ | |\__\/ | || | || | | | | |\_\/ / /\ \ \ / __/ | |_|_____ | \|__/ || | | | | |_|_____ / / |\ \ \ / _/ /______/ / /_______/| /___| | /______/ / /__/ /\ \__\ \ / / \______\/ \________/ \____\| \______\/ \__\/ \|__| \/ / \/ DEUTEX/DEUSF 3.6 July 1995 wad composition tool for Doom Copyright (c) Olivier Montanuy 1994/95 Copyright (c) André Majorel 1999-2005 Manual Edited by Kevin McGrail (hevkev=sfo+com) Trouble shooting and support: On Usenet: the newsgroup rec.computers.games.editing On Compuserve: The ACTION forum (Doom Utilities) Serious trouble or identified bug: E-mail directly to the maintainer amajorel=teaser+fr Note that this product is Freeware, and that support only depends on the good will of the involved people. Be tolerant. Don't expect prompt answers. ================= RELEASE NOTES FOR VERSION 4.5 ================== THIS MANUAL IS NOT UP TO DATE ! READ THIS FIRST ! For a complete list of all the changes between DeuTex 3.6 and Deutex 4.5, see the CHANGES file. Here is a quick summary of the important features. 1. The default transparent colour has been changed from cyan (0, 255, 255) to dark blue-green (0, 47, 47). If you try to build with DeuTex 4 a wad from old graphics files that use cyan (0, 255, 255) for the transparent areas, there will be no error message but the parts that were supposed to be transparent will come out as opaque, light blue or white areas. The easiest solution in the short term is to run DeuTex with the option "-rgb 0 255 255" when building. The best long-term solution is to change your images so that they use (0, 47, 47) instead of (0, 255, 255). For BMP and GIF images, you can do that very quickly by editing the palette. For PPM images, use the flood fill function of your graphics editor. 2. Flats are now put between FF_START and F_END so you don't need DeuSF anymore to put flats in pwads. "It just works, right out of the box !" 3. Doom alpha 0.4 and Doom alpha 0.5 are now supported. To extract the contents of the iwads, deutex -doom04 c:\doom0_4 -xtract deutex -doom05 c:\doom0_5 -xtract Some graphics are extracted as lumps (GNUM[0-9]). 4. Doom press release pre-beta is now supported. To extract the contents of the iwad, deutex -doompr c:\doomdemo -xtract 5. Hexen is now partly supported (still a lot to do). New command-line switch -hexen. To extract the contents of the iwad, deutex -hexen c:\hexen -xtract 6. Strife is now fairly well supported (some remaining glitches). New command-line switches -strife and -strife10. To extract the contents of the iwad, deutex -strife10 c:\strife -xtract (Strife 1.0) deutex -strife c:\strife -xtract (Strife 1.1 and above) 7. New command-line switch -doom2. 8. New command -usedidx. 9. Easier to build on Unix systems, especially Linux. On DOS and Windows, now builds with DJGPP, Cygwin and MSC 6.0. There shouldn't be any endianness problems now. 10. DeuTex is now libre (GPL + LGPL + PBMPLUS license). 11. The default graphics format on Unix is now PPM. 12. Sounds with sample rates different from 11025 Hz are now allowed. 13. Many arbitrary limits have been lifted. 14. Assorted bug fixes. -- AYM 2005-08-30 ================================================================== ------------------------ Data Utility License ------------------------- Doom(tm) is a trademark of Id Software, Inc. The Doom characters and the Id Software logo are trademarks of Id Software, Inc. Doom Copyright (c) 1993. Id Software Inc. All rights reserved. This utility product is not a product of Id Software, Inc. and has not been approved by Id Software, Inc. Id Software will not provide technical support for this product. The purchaser of this utility product may not distribute for money or other consideration any software data created and/or modified by the use of this utility product. ----------------------------------------------------------------------- ***************************** DISCLAIMER ***************************** 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 LICENSE for specific information. ************************** CONVIVIALITY ****************************** For obvious reasons of reliability and portability, this tool is not GUI oriented, and learning to use it will be as painful as learning to use some complex Unix command. If you're not a Unix kind of guy, get WinTex, a cool Visual Basic program that I wrote for people like you. It has all the power of DeuTex (since it can call DeuTex) but it's much easier to use. *********************************************************************** + *NEW* - Lines beginning with a '+' indicate information added since + the manual for DeuTex v3.1 came out. + DeuTex 3.6 is mainly compatible with version 3.4 to 3.1 but not with + versions 2.9 and below. Changes are minor, however. As of version 3.6, DeuTex/DeuSF can be considered as finished. Almost all the features a normal human would require are there I only need to add something to build/modify a wad fast, in order to facilitate the building of preview pwads. Normally, the join commands should make this useless, but you never know... The sources of DeuTex 3.4 are out, and those of DeuTex 3.6 should follow soon. They might be out when you read this manual. page i ************************** Table of Contents *************************** Data Utility License i Disclaimer i Conviviality i Table of Contents ii Features v What's New? vi ---------------------------- *** [PART ONE] GETTING STARTED *** 1 ---------------------------- Chapter 1 OVERVIEW 1 A) What is DeuTex? 2 B) Installation 2 C) Directories and DeuTex 4 D) What do I need? 4 E) What do I do? 4 F) What is DeuSF for? 5 G) What are the Palettes For? 5 Chapter 2 TEST-ME or What's inside TRINITY.wad? 7 A) About Test-Me 7 B) Listing the Directory 7 C) Decomposing TRINITY.wad 7 D) Recomposing TRINITY.wad as TRINIDAD.wad 8 E) Customizing TRINITY.wad 8 Chapter 3 WORKING WITH WADS 9 INTRODUCTION 9 A) How to Decompose a pwad 9 B) How to Create a pwad with new textures 10 C) How to Create a pwad with new sprites and flats 11 1) Sprite and flat replacement 11 2) Changing the number of sprite viewpoints 12 D) How to Create a pwad with new SOUNDS 14 Chapter 4 WinTex 15 page ii ********************** Table of Contents (cont) ************************ ----------------------------- *** [PART TWO] DETAILS, DETAILS *** 16 ----------------------------- Chapter 5 DIRECTORY STRUCTURE 16 A) levels/ 17 B) lumps/ 18 C) textures/ 19 D) sounds/ 20 E graphics/ 20 F) sprites/ 21 G) flats/ 21 H) patches/ 22 Chapter 6 DEUTEX COMMANDS 23 A) Complete Command Reference 23 B) Help Commands 23 C) Optional Commands 23 D) Commands to Compose or Decompose wads 25 E) Commands for merging pwads into the Main iwad 26 Chapter 7 DEUSF COMMANDS 28 A) Overview 28 B) Complete Command Reference 29 C) Help Commands 29 D) Optional Commands 30 E) Mandatory Commands 30 Chapter 8 FORMATS 31 A) The wad Creation Directive (wadINFO.TXT) 31 1) Overview 31 2) wadINFO.TXT format 32 3) An example wadINFO.TXT Listing 36 B) The Texture Definition File (TEXTURE1.TXT) 39 1) Overview 39 2) An Example TEXTURE1.TXT Listing 41 page iii ********************** Table of Contents (cont) ************************ --------------------------- *** [PART THREE] ALL THE REST *** 43 --------------------------- Chapter 9 NECESSARY STUFF 43 A) License Agreement 43 B) Legal Stuff 44 C) Where to get DeuTex/DeuSF 45 D) Version Information 46 E) Known Problems 47 F) Thanx 48 G) Final Words 50 APPENDICES I) Switch Textures in DOOM.wad 51 II) Animated Wall Textures in DOOM.wad 56 III) Sound names for Doom 58 A) Sounds found in BOTH Doom I and Doom II 58 B) Sounds found ONLY in Doom II 60 C) Converting DMAUD sounds for DeuTex 62 IV) DeuTex and DeuSF Command Summaries 64 A) DeuTex Commands 64 B) DeuSF Commands 65 page iv ****************************** FEATURES ******************************* ------------ DeuTex ------------ DeuTex stands stands for DEU's Texture Companion, because it used to deal only with Doom textures. Now it can do much more! DEU is a Doom level editor by Brendon Wyber and Raphael Quinet, and DeuTex was originally derived from the code of DEU 5.21. DeuTex uses various contributions for particular file formats. DEUTEX Features: - Ported on all Doom platforms (DOS,OS/2,Linux,SGIx,Unix) - Reverse engineer existing pwads. - Compose your own wall Textures, by reusing existing Doom patches or adding your own patches as .BMP or .GIF files. - Load sounds as .WAV, .AU or .VOC files. - Load PC Speaker sounds as a serial of number (in text). - Load music entries as .MUS files. (from MIDItoMUS) - Add your own floors. - Add your own sprites. - Simple wad creation directives from a text file. - Simple directory structure for the resources. - Work in batch mode, like a compiler. - A Windows shell can be used to make your life easier. - Compatible with Level editors (like DEU,WinDEU). - Merge a pwad into the main iwad, recreating the wad directory, so that ANY or ALL kinds of sprites and/or Flats can be defined, while distributing only the changed ones in the pwad. - Extract Graphics, Bitmaps and Lumps out of your favorite pwad, for contemplation or reuse. (WITH wad AUTHOR AGREEMENT ONLY!) - Check your pwad for errors in Texture definitions. - Create animated walls with (almost) any sequence of pictures. - Create a non repeating sky Texture. ------------- DEUSF ------------- DeuSF stands for DEU Sprite and Flats. It is mainly used to compensate a bug in Doom sprite and flats handling. DeuSF was inspired by DMADDS by Bernd Kreimeier, but is more powerful and much cleaner. Like DMADDS, DeuSF compensates for a bug in Doom concerning the treatment of external sprite and flat pwads. It will enables you to distribute pwads containing only the sprites and/or flats that you wish to replace. There are some caveats here, so read the manual! DeuSF can read DMADDS files, but its' preferred pwad composer is of course DeuTex, since pwads composed for DMADDS are very dirty inside. DEUSF Features: - Recreate a complete sprite and/or Flat pwad from a partial sprite and/or Flat pwad and the main wad of Doom. WARNING: The sprite names VILE[, VILE\ and VILE] are not valid DOS file names, so DeuTex replaces them with VILE$, VILE@ and VILE# when extracting them to files. Use these names for your files, too. page v ***************************** WHAT'S NEW? ***************************** + New in DeuTex 4.0 + - Lots :-) + New in DeuTex 3.8 + - ? New in DeuTex 3.6 - Possibility to take an entry from an existing pwad If the file that contains your entry as extension .wad, deutex will attempt to read it, and find your entry inside it. - Bug corrections (there was still some left...) - Wall patches must now be explicitly declared. If they are not, DeuTex will try to find them in PATCHES\, as usual. New in DeuTex 3.5 - Bug corrections, as usual (there can't be much left!) - New command -s_end for those that use new sprite names... - Detection of textures that can cause Medusa effect Added in DeuTex 3.4 - Many many corrections of small bugs (and compiler errors, dammit!) - function -usedtex to find the texture use in all levels - Overwrite switch (-o) to replace data (when you really want it). - A fully working merge and join function (I hope) - Improved support for WinTex Added in DeuTex 3.3 - Added a -get function to retrieve a single wad entry - Improvements to -merge so that it can be used with Heretic NOTE: HERETIC V1.0 CAN'T USE EXTERNAL SPRITE wad. THIS IS A BUG IN HERETIC, NOT DEUTEX, DEUSF OR NWT - Sound formats corrected (at least) but compression not supported. - Now -merge and -app, -join preserve the file time, not only the contents so that you can still patch your iwad after -merge. - A _DEUTEX_ entry is added in the wad directory - New [MUSICS] section and MUSICS subdirectory. - Small patch to prevent DCK from bugging at modified iwads - DeuTex can now read duplicate sections in Wadinfo.txt when extracting new data, if wadinfo.txt exist , it appended SUPPORTED Doom registered 1.1 to 1.9 and above Doom2 1.6 to 1.9 and above Heretic registered 1.0 and (probably) above NOT SUPPORTED (by request of Id software) Doom shareware Heretic shareware It is possible for a hacker to modify DeuTex/DeuSF and make it compatible with Doom or Heretic shareware. If you're *that* short of money that you're ready to hack a prog to save 40$ and the pleasure to be supporting one of the very best game company, please don't distribute your version of DeuTex/DeuSF, because I have no time to spend answering questions about a hacked DeuTex that could possibly fail very differently than the original. page vi ---------------------------- *** [PART ONE] GETTING STARTED *** ---------------------------- CHAPTER 1 ****************************** OVERVIEW ******************************* DeuTex is a GREAT program! (preceding claim inserted over the objections of Olivier Montanuy) ;-) *********************** A Note About This Manual *********************** There is a lot of redundancy in the manual. This is intentional. The manual is intended to be used as a reference. When you have a question on a particular aspect of DeuTex, look up a likely entry in the Table of Contents, and read that entry. It should have the information you need. This is to prevent you from having to jump around from page to page to figure out a procedure in DeuTex. This doesn't mean that sections are identical. Each section attacks a problem from a different viewpoint. If one section doesn't help you, maybe a different 'angle' will. ************************************************************************ This manual has a lot of trees in it. This chapter will give you a view of the forest. DeuTex and DeuSF are powerful programs that will let you do almost anything you can imagine in composing or manipulating pwads. Notice the word composing. Deutex is an Orchestra Conductor. It can perform whatever music you write for it brilliantly, but you must supply the musicians. A pwad consists of many parts. DeuTex coordinates those parts to give you the pwad you desire, but it doesn't create them. With DeuTex you have access to all the resources in the Doom1 or Doom2 iwads. Since it does so many things, it might seem a little confusing at first glance. Don't worry. If you are familiar with Doom (read Matt Fell's Doom specs and Hank Leukart's DoomFAQ), then all you need to learn about DeuTex is it's organization. There are so many resources in Doom that it isn't reasonable to put them all in one directory. DeuTex uses a subdirectory for each entry type. Using these subdirectories is easy once they're explained. Deutex makes it possible to use a simple, straightforward method for working with custom graphics (and sounds). The approach is as follows: 1) Put your resource files in subdirectories such as FLATS, SPRITES, etc., further discussed below. 2) Use a `Wadinfo' file called something like `goodies.txt' to tell Deutex how to assemble the resources into a pwad. 3) Run `deutex -make goodies.txt goodies.wad' to make the pwad. Now you can play your level with the resources, without any fuss (unless, of course, something has gone wrong along the way). page 1 This method works for any resource. You can make sound-only wads that will play with any version of Doom. You can include Level maps in a multi-level pwad. DeuTex will put the Levels where you want them, regardless of the internal EnMm OR MAPnm of the Level. If the finished pwad doesn't contain new sprites or Flats, it can be played as is. Otherwise, it can be rendered playable with DeuSF, which can be freely distributed with your pwads. The DeuTex Visual Basic shell let's you use the Windows environment to distribute those entries in the right directory, and then execute the -make command. It doesn't change the way DeuTex works, it only makes your life easier. --------------- A) WHAT IS DEUTEX? --------------- DeuTex is a pwad compiler. It allows you to organize ALL the resources you modify, and group them into your pwad in a single step. This eliminates the need for running a different program for each type of editing you want to do (DMAUD, DMGRAPH, DMADDS, etc). DeuTex is NOT a: map editor, (use DEU, DoomCAD, WadEdit...) nodes builder, (use DEU, BSP, IDBSP,...) reject map builder (use RMB or REJECT) DOOM.EXE editor (use DEHACKED) Your Level map with nodes, reject and blockmap already calculated is just another resource to DeuTex. If you don't want to redefine or create Textures, Flats, sounds, etc. in your pwad, you don't need DeuTex. On the other hand, if you redefine LOTS of stuff, you'll wonder how you ever got along without it. If you've worked with wads before, you know how many times you have to go in and change something! With DeuTex, you just edit the resource you want to change, throw it back in it's subdirectory, and run a batch file to put everything together again. ------------ B) INSTALLATION ------------ DeuTex comes in zipped format. Naturally, you need a copy of PKUNZIP (v2.04G) to unzip it. If you don't have one, go get it! It's probably available the same place you got DeuTex. PKUNZIP also exist for Unix. The file name is DEUTEX35.ZIP or something like it. This manual is valid for DeuTex versions 3.6 and above. Some information is not applicable to previous versions, and may cause you problems. Be forewarned! Installing DeuTex: DeuTex and DeuSF should be put somewhere in your path, e.g. under C:\DOS in DOS, ~/bin under Linux/Unix, etc. This is not ABSOLUTELY necessary, as you can put a copy in your working directory each time or specify path names in all the commands, but, believe me, it makes life much simpler. page 2 You should enable DeuTex/DeuSF to locate your Doom or Doom2 files by creating an environment variable DOOMWADDIR that points to your Doom path like this: For DOS, put the line 'SET DOOMWADDIR=C:\GAMES\DOOM' in AUTOEXEC.BAT. For Unix with sh, ksh or Bash, use 'export DOOMWADDIR=~/games/doom' in .profile. For Unix with csh or tcsh, use 'setenv DOOMWADDIR ~/games/doom' in .tcshrc. This is more important for the Linux/Unix version, since with DOS the command deutex -doom will achieve the same result. In DOS, it's possible to get an 'out of environment space' error if you have too many variables defined in autoexec.bat (including path, etc). If this occurs, use DOS Help for the SHELL command to find out how to increase your environment space. Of course, DeuTex will only work if the REGISTERED version DOOM.wad or DOOM2.wad is available. Should you be in dire need of disk space, or should you wish to use DeuTex on a machine that can't run Doom, you can use DeuTex to build a fake DOOM.wad or DOOM2.wad, keeping only the structure of the directory and the entries PLAYPAL, TEXTURE1, TEXTURE2 and PNAMES. Of course, to do this, you first need a complete registered DOOM.wad or DOOM2.wad, and even then it's a real pain. Beware to keep that file for yourself ONLY. The archive for DeuTex 3.6 contains the following files. For illustration purposes, the diagram assumes you put DEUTEX36.ZIP in the root directory (C:\). Directory information is embedded in the zip file, so use the PKUNZIP -d option: PKUNZIP DEUTEX36.ZIP will produce: C:\deutex36.zip |_ \DEUTEX\ deusf.exe - DeuSF program. deutex.exe - DeuTex program. dtexman6.txt - This manual. file_id.diz - For BBS use. readme.txt - Short description of DeuTex/DeuSF. doom.pal - Doom palette, PaintShop Pro format. heretic.pal - Heretic palette, PaintShop Pro format. test-me.zip - a ZIP file containing batch files to test DeuTex with Trinity.wad You may end up moving the palettes if you want them in their native application's directory. WinTex, the Visual Basic shell for DeuTex, has gone so huge and powerful that it can't be included in the deutex files anymore. It will be available separately, as WINTEX35.ZIP. page 3 ---------------------- C) DIRECTORIES AND DeuTex ---------------------- Chapter 5 tells you all about the directories DeuTex uses, but this section will give you the general picture. I'm going to use an imaginary cake making machine to explain DeuTex's directories (I know, I know, it's stupid! ). To make cake with this machine, you put your flour in one, container, raisins in another, sugar another, milk, icing, walnuts, chocolate, eggs, etc. All your best stuff, each in it's own place. Then you flip the switch, and the machine thumps and smokes, and voila! Cake! DeuTex works in the same way . You put your Map in one box, sounds in another, textures, patches, graphics, lumps, sprites and flats all in their own boxes. If you don't want raisins today, leave the sprites box empty. When all is in place, flip the switch (DeuTex -make, in a batch file preferably), DeuTex thumps and smokes for a little while, and voila! pwad! --------------- D) WHAT DO I NEED? --------------- ************************** User Requirements ************************* ATTENTION: DeuTex is not completely trivial to use. It requires a fully functional processing unit, with a least 10000 meg of available neurons, some basic DOS and Doom specs dynamic libraries and at least 1 or 2 hours of spare processing time at a minimum 80% attention rate. You have been warned. SUGGESTION: If you use DeuTex, try New Wad Tool, too. The two tools combine very well together under DOS. (NWT is not available for other O/S). ************************ Hardware Requirements *********************** This program is an ordinary DOS executable, compiled in a HUGE memory model, with 386 instructions. It does not make use of a math coprocessor. It should run with about 500k of free base memory, or less. It might not run under a 286. It was tested on a Compaq LITE 4/33c and an IBM Thinkpad 755c. DOS/GO32, Unix, Linux, OS/2, SGiX and Alpha versions are also available. ------------- E) WHAT DO I DO? ------------- Please read this Manual before asking questions. I know it's boring, but this IS freeware, and I have limited time to support it. Bug reports ARE appreciated IF they come with the files you were using when the bug occurred, and a full description of it. Read and be familiar with all the Doom literature you can, especially the 'unofficial' DOOM SPECS 1.6 by Matt Fell. You don't need to read the file formats, but you need to understand what the different entries are for, and the tricks and limitations of Doom. page 4 DeuTex makes some checks on your pwad, but I don't have time to program for all possible errors. Become familiar with the various editors you need to create the resources used in this program. DeuTex does not edit things. It puts the things YOU edit together. For editing, use the best sound or Graphic editor you can afford. When the foregoing is done, you take all your cool stuff. You put it in DeuTex's boxes. You give DeuTex the directions on what to DO with your stuff. You run DeuTex. That's All, Folks. ------------------ F) WHAT IS DEUSF FOR? ------------------ DeuSF is a program to help overcome some of Doom's limitations, and still be able to distribute a reasonable sized pwad. With sprites and flats, you have to replace EVERYTHING in order for Doom to work right. This makes for a big pwad (3 to 5 megs), and it's illegal to take Id's sprites or flats from Doom, put them in your pwad, and then distribute them. DeuSF allows you to replace as few sprites and flats as you desire, and distribute ONLY THOSE with your pwad. With the appropriate batch file, it will change things at the USER's site to enable your pwad to play, without stepping on toes, or asking people to download multi- megabyte single Level pwads! Another advantage of DeuSF is that it makes sprite pwads playable with either Doom or Doom2 using the same install.bat file. Isn't that great? -------------------------- G) WHAT ARE THE PALETTES FOR? -------------------------- doom.pal (Doom palette, for PaintShop PRO 3.0 shareware program) heretic.pal (same, but for Heretic) These are the color palettes used by Doom and Heretic. If you edit or create any graphics (patches, sprites, etc.) in your favorite graphics program, the colors will most likely be different from the ones used in Doom. When they are inserted in a pwad, they need to be 'quantized', which is a fancy word for color-matched. Although this sounds simple, it can actually be quite involved. DeuTex can quantize colors, but it's not optimised for that, so quantization might be quite poor: there is no dithering. Quantisation of colors is a serious job, meant to be done by specialised programs. page 5 What should you do before inserting a picture with DeuTex? * AVOID regular patterns, like squares/stripes. These patterns are prone to create ugly aliasing when scaled by Doom. * SMOOTH it! I mean, apply a low pass filter so that it appears blurred. This will also hide some of the aliasing effects of scaling. * QUANTIZE your colors with one of the supplied Doom palettes. DeuTex is optimised for the original Doom palette. If you use another palette, it will be slower. DeuTex will quantize your colors to the Doom colors using a strange alchemy. No dithering. * TRANSPARENT areas should be made of A UNIQUE COLOR, preferably CYAN (r=0,g=255,b=255, but you can specify another color to DeuTex.) WARNING: Some lame programs don't support full 0-255 range. CYAN could be r=0, g=252, b=252. Experiment first. The enclosed palettes are in the format of two good graphics programs. Use them to quantize your pictures before you feed them to DeuTex. doompal.pal is in the format used by PAINTSHOP PRO v2, a popular shareware graphics program with excellent color conversion capabilities. To convert with doompal.pal in PAINT SHOP PRO: - Load the file you want to convert. - Select *Colors* from the menu bar. - Select *Load Palette* from the drop-down menu. - Browse to find doompal.pal and select it. - In the 'apply palette to image using' box, select *error diffusion*. - Select *OK*. PaintShop Pro will then quantize your image to the Doom palette. - Select *File* from the menu bar. - Select *Save As* from the drop-down menu. - Select *BMP - OS/2 or Windows Bitmap* from 'List files of type'. - Select *Windows RGB Encoded* from 'File Sub-format'. - Select *OK*. Doom will now display your Graphic pretty much as you expect. If you want to make a .PBM (portable bitmap), use ppmquant on your picture, with doompal.ppm as the reference for colors. Alternatively, if you extract a Doom Graphic with DeuTex, it will contain the Doom palette. You can then feed it to your favorite program, and let it extract the palette for later reuse. WARNING: Experiment with this first, as your program might not do what you expect it to. For example ZSoft's PC Paintbrush will load the Doom Graphic correctly and allow you to save the palette. However, if you take a 24 bit image and load the palette, nothing will happen. You can let PC Paintbrush convert the image to 256 colors (which it will do poorly), and then apply the palette. The results will be grotesque, because it doesn't quantize when applying a palette. A Doom palette saved in this program would be useful only for Graphics you want to hand-draw from scratch. The moral is, if you don't know what you're doing, experiment first before using a Graphic you don't want to lose. page 6 CHAPTER 2 *************** TEST-ME or What's inside TRINITY.wad? ***************** ------------- A) About TEST-ME ------------- TRINITY.BAT let's you have a quick overview of some of the capabilities of DeuTex so you can decide if it's worth the trouble. TRINITY.BAT does the following: It lists the contents of TRINITY.wad (with identifications). It decomposes TRINITY.wad and builds TRINIDAD.wad. All this in only 3 trivial DeuTex commands. Requirements: - You must have TRINITY.wad, the great pwad by Steve McCrea. (available on ftp.cdrom.com as TRINITY2.ZIP and in the Compuserve GAMERS FORUM LIB 8 as TRINTY.ZIP) - Doom must be in the \DOOM directory (\DOOM2 could work too) - TRINITY.wad must be in the current directory. - You must have *some* room left on your disk :-) - You must be running DOS 5.0 or higher. - You must NOT reuse any part TRINITY.wad without crediting Steve. Description of the file, TRINITY.BAT: ---------------------- B) Listing the directory ---------------------- rem ***DeuTex*** deutex -doom \doom -wadir TRINITY.wad ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ (a) (b) (a)---> This tells DeuTex that DOOM.wad and DOOM.EXE are in the \DOOM directory. OPTIONAL. (b)---> This tells DeuTex to list the directory of TRINITY.wad reporting the entry types. Types *could* be wrong, but not with Trinity. ------------------------ C) Decomposing TRINITY.wad: ------------------------ rem ***DeuTex*** deutex -doom \DOOM -dir . -xtract TRINITY.wad ^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ (a) (b) (c) (a)---> The same as before. (b)---> This tells DeuTex that it must store the result in '.' (which is the current directory). You could skip (b), since '.' is the default, or you could specify another directory, like -dir TEST. (c)---> This tells DeuTex to extract all entries from TRINITY.wad. page 7 ---------------------------------------- D) Recomposing TRINITY.wad as TRINIDAD.wad: ---------------------------------------- rem ***DeuTex**** deutex -doom \doom -dir . -make wadINFO.TXT TRINIDAD.wad ^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ (a) (b) (c) (d) (a)---> The same as before. (b)---> The same as before. (c)---> This tells DeuTex to create a new pwad, from the creation directives contained in wadINFO.TXT. (d)---> This is the name of the created pwad. ------------------------ E) Customizing TRINITY.wad: ------------------------ You can edit wadINFO.TXT, the format is pretty simple to guess. (see Chapter 8 - FORMATS for a precise definition.) - A line that begins with a ';' or '#' is a comment. DeuTex ignores it. - Don't touch any lines with [xxxx] (they are section delimiters). + Lets look at the [MUSICS] section: + [MUSICS] D_E1M1 + This tells DeuTex to go into the \MUSICS subdirectory and get a file called D_E1M1.MUS, which is the music of TRINITY.wad. You might wish to delete this D_E1M1 if your sound card crashes while playing trinity. You can add your own music, for Episode 1 Mission 2 by editing: + [MUSICS] D_E1M1 D_E1M2 Of course, the file D_E1M2.MUS must exist... You can generate it from D_E1M2.MID (MIDI format) by using MIDI2MUS. BEWARE: DeuTex is NOT fool proof yet. It should not crash your computer, but the generated pwad may crash Doom if you make mistakes. I'm very sorry for this, but I have more urgent optimizations to do than foolproofing. However, the pwad generated here should not crash Doom, if you use the real TRINITY.wad as a basis. page 8 CHAPTER 3 ************************** WORKING WITH wads ************************** ------------ A) INTRODUCTION ------------ Read the DOOM SPECS: Sorry. This is still unavoidable, because of the various tricks and limits of Doom. If you have a problem, there is a VERY GOOD chance it's referred to somewhere in Matt Fell's SPECS. NOTE: In the following discussion, avoid these common mistakes: Hall of Mirrors with new Textures: First, create your Level. Then, build the nodes and reject. Then add the new Textures. Why? We don't know. leonardc=halcyon+com reported he saw a hall of mirrors with old versions of DeuTex that didn't first load the old Doom Textures. It seems to be a problem with the node builders. Tutti Frutti and Medusa Effect: See the DOOM specs, and Chapter 8 - FORMATS. If Doom attempts to display part of a Texture not covered by a patch, you'll see some ugly garbage (usually has pinks and greens, thus 'Tutti Frutti'). The same thing happens if you use more than one patch on a Texture with transparent areas, or walls with see-thru portions on upper or lower Textures. If the area is big enough, it will slow the display to a crawl ('Medusa Effect' - Looks like snakes and turns you to stone). Doom reports a void column and exits: One of your Textures has a column with no patches. Use DeuTex -check on a pwad before running Doom. It reports Textures that have void columns. Other bugs: Mail me a description of the bug, together with any configuration files. Don't expect a quick answer, though. ----------------------- B) How to decompose a pwad ----------------------- First check that all the entries are identified correctly: DEUTEX -wadir NEWBIE.wad This will list the directory. Then try: DEUTEX -unused NEWBIE.wad This will tell you if there is any wasted data in the pwad. It's always funny to see how DMGRAPH and DMAUD waste *some* data. This won't tell you about any data wasted by incorrect entry formats, though. page 9 To extract entries in the pwad: + +DEUTEX -get SPOSA1 DOOM.wad Extract the entry SPOSA1 from DOOM.wad + DEUTEX -xtract NEWBIE.wad Extract all the entries in NEWBIE.wad. A directory structure is created, and the entries are put in the subdirectories. A file wadINFO.TXT is created, to describe the contents of the pwad. DEUTEX -sound -xtract NEWBIE.wad Only the sounds are extracted and placed in the \SOUNDS subdirectory, which is created if it doesn't exist. NOTE: Some obsolete pwad tools used to declare patches, Flats and sprites without the normal markers. DeuTex attempts to compensate, but it could be that some entries will be identified incorrectly. DeuTex will then consider them as LUMPS or as GRAPHICS. So if you don't find a sprite in .\SPRITES\, look in .\GRAPHICS\. You will then have to declare them in the [SPRITES] section again. Once you have decomposed a pwad, you can rebuild it with: DEUTEX -make wadINFO.TXT NEWBIE.wad wadINFO.TXT already exists, because it was automatically created during the extraction of NEWBIE.wad (cool, no?). Make sure you delete or move the previous version of NEWBIE.wad before you remake it, because DeuTex will not overwrite your files (you might not like it :-]). NOTE: DEUTEX puts a signature in the first few bytes of a created pwad, to identify which version of DEUTEX was used. -------------------------------------- C) How to create a pwad with new Textures -------------------------------------- First list Doom's Textures, as a reference: DEUTEX -texture -extract This will extract all the Textures from the main iwad. They will be written to TEXTURE1.TXT (and TEXTURE2.TXT for Doom1 only). These text files will be placed in the subdirectory \TEXTURES, which will be created if it doesn't exist. These files make it easy for you to redefine existing Textures by cutting them out and pasting them into YOUR Texture definition file. Note that it's not wise to redefine textures from Doom or Doom, except if you're redefining an animation. When you will wish to define new textures, you will put those textures in a texture file, which is no more than a specially formatted text file (no, it's not a picture) that you will put in .\TEXTURES, and that you will declare in the [TEXTURE1] section of wadINFO.TXT. This Texture file need not contain all the textures in Doom, only those that you wish to redefine. It's a bad idea to keep all the textures from Doom in your texture file. Let DeuTex handle that. There can be more than one texture file, which is convenient if you have already created textures for another wad and wish to import them. page 10 Note that if you define a texture more than once, only the last version read by deutex will be put in the wad. Not also that if you define a texture that has the same name as a texture NOTE: For DOOM1/Heretic only, use one file for redefined Textures from OLDTEX1.TXT, and another file for redefined Textures from OLDTEX2.TXT. Since DeuTex v3.3, wadINFO.TXT uses a second Texture section called [TEXTURE2] for redefined OLDTEX2 files. DeuTex 3.3 doesn't care if OLDTEX1.TXT or OLDTEX2.TXT exist. DeuTex 2.x used to require that all the old textures be present, but now DeuTex 3.3 first read the internal Doom texture definitions, then reads the file you tell it to read, for new definitions. If you mistakenly define the same Texture in multiple files, only the last declared version will be used. Of course, that means that if you redefine a Doom texture your version will be used. Declare TEXTURE1 in the [TEXTURE1] section of wadINFO.TXT. Then build your pwad: DEUTEX -make wadINFO.TXT NEWBIE.wad At this point, it would be a good idea to check your new pwad for Texture errors: DEUTEX -check NEWBIE.wad ----------------------------------------------- D) How to create a pwad with new sprites and Flats ----------------------------------------------- ******** 1) Sprite and flat replacement BEWARE: Sprite replacement is tricky. If some needed sprites are missing Doom will lock up. Check your work often. Put your sprite files in \SPRITES in .GIF or .BMP format. Put your Flat files in \FLATS in .GIF or .BMP format. Declare your sprite NAMES in the [SPRITES] section of wadINFO.TXT. Declare your Flat NAMES in the [FLATS] section of wadINFO.TXT. Use only the NAME in wadINFO.TXT, without the .GIF or .BMP extension. Since DeuTex 3.1: The '=' label lets your sprites keep the names YOU have given them. It tells wadINFO.TXT what Doom sprite you mean to replace. This enables you to name your sprite files as you damn wish. If you want to replace *ALL* of the sprites and Flats in Doom (crazy): DEUTEX -iwad -make wadINFO.TXT NEWBIE.wad NEWBIE.wad will be directly usable by Doom. Remember: replacing only part of the sprites and Flats mean you'll need DeuSF to install your pwad, but it will be compatible with ALL versions of Doom and Doom2. Redefining all the sprites is not a good idea unless you really mean it. page 11 To replace *SOME* of the sprites and/or Flats in Doom (better): DEUTEX -make wadINFO.TXT NEWBIE.wad This NEWBIE.wad will be much smaller and easier to distribute. BUT: This NEWBIE.wad will cause Doom to lock up when it starts!(bad) So, if you want to replace only *SOME* of the sprites and Flats in Doom, you have 3 choices: DEUTEX -merge NEWBIE.wad Modifies DOOM.wad or DOOM2.wad. (Safe, fast, and small) DEUSF -append NEWBIE.wad Modifies NEWBIE.wad. (Safer, still fast, wastes some space) DEUSF -add NEWBIE.wad NEWBIE2.wad Creates NEWBIE2.wad. (Safest, not slow, more space wasted) + + NEW! To merge two pwads that both redefine sprites and/or Flats: + + DEUSF -join FIRST.wad SECOND.wad (FIRST.wad now contains both wads) NOTE: The steps above are performed at the end users' site, preferably from a batch file supplied with your pwad. This means the user must have DeuSF, which can be distributed freely with your pwad, or DeuTex, which has some restrictions on distribution. See the License Agreement at the end of this manual for the restrictions on distributing DeuTex. The -sprite command is used to add only sprites, ignoring the Flats: DEUSF -sprite -app NEWBIE.wad The -flat command is used to add only Flats, without the sprites: DEUSF -flat -add NEWBIE.wad NEWBIE2.wad ******** 2) HOW to ADD or REMOVE SPRITE VIEWPOINTS DeuTex allows you to alter the number of viewpoints a sprite displays in your pwad. DOOM.EXE predetermines the 'behavior' of a given sprite name, but it doesn't predetermine the number of viewpoints. A sprite MUST, however, always have either ONE viewpoint or EIGHT viewpoints. Viewpoints are numbered as follows: Front 1 2 | 8 \____|____/ | | 3 -- | SPRITE | -- 7 |_________| / | \ 4 | 6 5 page 12 The FULL NAME of the sprite determines the viewpoint of that sprite: BAR1A2.bmp \ /| \________________ \/ | \ ________________/ | The last number is the viewpoint. A / | zero here means the sprite has only The first four letters are the | one viewpoint. If not zero, there sprite name as recognized by | MUST be 8 files for each 'frame' of DOOM.EXE. They are the same for | the Sprite. all entries of a given Sprite. | | This is the 'frame' number of the Sprite. Animated Sprites will have consecutive letters here for each frame (A is frame one, B is frame two, etc.). DOOM.EXE predetermines how many frames a Sprite uses, so you can not animate an electrical column, for instance. Sometimes, you will see a Sprite entry that has 2 viewpoints in one Sprite, like BOSSA2A8. This means that the same Graphic is used for viewpoints A2 and A8 (front-left and front-right). When Doom sees this, it uses the Graphic as is for A2, and mirrors it for A8. In the above example BAR1 is the Barrel Sprite. Doom does a 2 frame animation on barrels (the slime flickers), so the whole entry is: BAR1A0 BAR1B0 This disregards the explosion (BEXP) Sprite that is used when you shoot a Barrel. If you want to change the Barrel Sprite to an 8 viewpoint Sprite, you will need to create 16 Graphics: BAR1A1 BAR1B1 BAR1A2 BAR1B2 BAR1A3 BAR1B3 BAR1A4 BAR1B4 BAR1A5 BAR1B5 BAR1A6 BAR1B6 BAR1A7 BAR1B7 BAR1A8 BAR1B8 This gives you 8 viewpoints for EACH frame of the animation. If you only replaced BAR1A1 thru 8, you would see your new Graphic flash to a barrel a couple of times a second, because you didn't replace the 2nd frame. If you add a 3rd frame (BAR1C1 etc.), it will be ignored by Doom because DOOM.EXE already knows a barrel has only 2 frames. page 13 Alternatively, you could take an Imp and give it only 1 viewpoint by taking only one of the views for each animation frame and naming it TROOA0.bmp (with the correct letter for the frame you're using). The Sprite will look kind of funny moving around, since it will only face one direction the whole time. + Special Sprites replacements: + + Some of you like to define their own sprites names, via a dehacked + patch. This trick is useful, because if you use custom sprite names + in your pwad, then it need not be completed by all the sprites from + the iwad. However, it will need a S_END appended at the end, otherwise + the game will not work. + So use the switch -s_end when you build your sprite wad with DeuTex. + Example: deutex -s_end -make myweapons.wad ---------------------------------- E) How to create pwad with new sounds ---------------------------------- First put your sound files in the .\SOUNDS directory. Then, declare the sound NAMES in the [SOUNDS] section of wadINFO.TXT. See APPENDIX IV for a listing of the sound names recognized by Doom. Then build your pwad: DEUTEX -make wadINFO.TXT NEWBIE.wad Sound effects: [DSxxxxxx.WAV or DSxxxxxx.AU] Supported formats are WAV, AU (Sun Audio) and VOC. Use only the 8 bits per sample, non-compressed, mono sounds. Do not use Stereo, 16 bit sounds or ADPCM compression. PC speaker sounds: [DPxxxxxx.TXT] Text files containing a list of numbers from 1-255. Musics are different from sound files. They describe only the notes to be played. They can't be obtained from normal sounds. There is one music defined for each level of Doom or Heretic. It has a special name, that is related to the level name (except in Doom2) Musics are declared in the [MUSICS] section, and placed in the .\MUSICS directory. Music: [D_xxxxxx.MUS] They must be in MUS format. You can convert MIDI files to MUS files by using MIDI2MUS.EXE (thanks to -dtt-> of Id software). You can get a list of musics by typing: deutex -musics -wadir This will help you guess the names of the musics. page 14 CHAPTER 4 ************************** Visual Basic Shell ************************** ------------------------------------- WinTex The MS Windows shell for DeuTex. version 3.41 ------------------------------------- WinTex 3.41 is a tool designed to make DeuTex real easy to use. It runs under Windows, and is written in C and Visual Basic. WinTex will prepare the data that DeuTex will compile into a wad. It's real easy to figure out, once you know how deutex works, and it will do for you all the stuff that deutex can't help you do (like adjusting the sprites offsets, composing the textures). With WinTex, you can use your own level editor, sound editor, music editor, picture editor, text editor, node builder, reject builder, and rely on good old DeuTex to make the tedious job of wad composition and wad merging. Actually, the windows part is only for the presentation, not for the real work. Windows is too unsafe to do any serious job... WinTex is the best way to use DeuTex, provided you have Windows 3.1. (WinTex is a 16-bit application, to spare you compatibility troubles) You will need VBRUN300.DLL in your windows/system directory, of course, as this is a Visual Basic application. The other DLL and VBX are provided with WinTex. page 15 ----------------------------- *** [PART TWO] DETAILS, DETAILS *** ----------------------------- CHAPTER 5 ************************* DIRECTORY STRUCTURE ************************* DeuTex uses the following directory structure to store Doom entries. First create a directory (call it MYwadIR or whatever) for your pwad. Make sure DeuTex is on your path, or put a copy of it in MYwadIR. Put a copy of the pwad you are working on (MYwad.wad) in MYwadIR. Type: DeuTex -xtract mywad.wad DeuTex will automatically create the appropriate subdirectories and put all the wad's entries in the proper place. It will also create a file named wadINFO.TXT in MYwadIR. If your pwad is a bare map Level with no additions yet, you should get something like: \MYwadIR\--------mywad.wad | wadinfo.txt | DeuTex.exe (optional, if not on your path) |_ \LEVELS\------EnMm.wad Note that DeuTex will not OVERWRITE any existing files. In the example above, if you type DeuTex -xtract AGAIN, you will get an error message telling you the files already exist. You have to delete wadinfo.txt and EnMm.wad (or move them somewhere else) for xtract to work again. If you lose something you wanted to keep, don't blame DeuTex, it's innocent! Now type : DeuTex <-doom doom directory> -textures -extract DeuTex will read the Textures from Doom.wad or DOOM2.wad, list them in a file called TEXTURE1.TXT (and TEXTURE2.TXT for DOOM 1) and store them in a directory called \TEXTURES, which it will create if it doesn't exist. NOTE: The <-doom doom directory> command is optional. Take a look at Chapter 6 - DEUTEX COMMANDS for a more complete description of when you should use it. Your working directory should now look like this: \MYwadIR\-----mywad.wad | wadinfo.txt | DeuTex (optional) |_ | \LEVELS\----EnMm.wad |_ \TEXTURES\---texture1.txt texture2.txt If your pwad had any other resources (Sprites, Flats, sounds, etc.) in it and you used DeuTex -xtract, it would extract those resources, too. Then it would create the proper directory and store them in it. page 16 If you want to add something to your pwad, put it in the proper subdirectory (create it if it's not there), and tell wadinfo.txt about it. Chapter 8 - FORMATS describes wadinfo.txt in detail. Then type: DeuTex -make wadinfo.txt mywad.wad DeuTex will read wadinfo.txt and go get all the resources it asks for from the directories. Then it will create mywad.wad from them. Note that if you create a pwad from the above example, it won't be any different than what you started out with! You need to put some ingredients into the mix before you see any results. THAT's what the other directories are for. Again note that DeuTex won't overwrite mywad.wad if it exists. Since most of the stuff you'll do with DeuTex will be from a batch file, have it handle your housekeeping whatever way you like. Something like the following works pretty well: del mywad.wad DeuTex -make wadinfo.txt mywad.wad copy C:\DOOM\wads\mywad.wad mywad.bak copy mywad.wad C:\DOOM\wads\mywad.wad This way, if you find out you've really screwed things up when you test your pwad, there's always a copy of the previous version to use. DEUTEX SUBDIRECTORIES: -------- A) \LEVELS -------- 'Bare' pwads go here! A bare pwad is one that you have edited and constructed the nodes, reject, and blockmap. The pwad will then contain only the following 11 entries in IT'S directory: EnMm(MAPnm), THINGS, LINEDEFS, SIDEDEFS, VERTEXES, SEGS, SSECTORS, NODES, SECTORS, REJECT, and BLOCKMAP. BEWARE: BLOCKMAP REJECT SSECTOR SEGS are not optional! they must have been generated by your Level editor (along with BSP, IDBSP, REJECT, RMB, whatever). THE FILES PUT HERE MUST BE DECLARED IN THE [LEVELS] SECTION OF wadINFO.TXT. ALL FILES MUST BE IN THE FORM EnMm.wad OR MAPnm.wad OR EQUATED TO EnMm or MAPnm in wadINFO.TXT. Suppose you have edited two Levels named PLAGUE.wad and E3M4.wad. You want the combined pwad to replace E1M2 and E3M4 in DOOM.wad. You would edit the [LEVELS] section of wadINFO.TXT to read: [LEVELS] E1M2 =PLAGUE E3M4 This tells DeuTex to look in the LEVELS\ subdirectory for PLAGUE.wad and E3M4.wad and to combine them in the final pwad as E1M2 and E3M4. page 17 ------- B) \LUMPS ------- Lumps are raw data for Doom with the extension .LMP. If you have edited or created any of them for your pwad, put them here. The following files are the LMPs used by Doom. You can insert something else if you like, and Doom will ignore it. It's a mystery why anyone would do this, but wad builders are a mysterious bunch! *********************** Lumps recognized by Doom ********************** PLAYPAL.LMP Color PALETTES (14 of them consisting of 256 RGB triplets each - 768 bytes/palette). The first one contains the normal Doom colors. The others temporarily 'tint' the screen colors for different events in Doom. (Item pickup, Hurt and Berserk Reds, Radsuit Green etc...) COLORMAP.LMP Color MAPS. There are 34 of these,consisting of 256 bytes each. These are NOT RGB triplets. They map whatever PLAYPAL currently being displayed by Doom to darker colors corresponding to the light level in a sector. These mapped colors are what you see on the screen. The first map (map 0) corresponds to a light level of 247-255, and doesn't change the display at all. The 32nd map (map 31) corresponds to a light level of 0-7 and maps almost all colors to the darkest one in the presently use PLAYPAL. Map 32 makes everything black and white for 'invulnerability'. Map 33 is all zeros. ENDOOM.LMP Text displayed when leaving Doom. Use A program like TED or ENDOOMER to edit this text. (DO NOT REMOVE THE ID COPYRIGHT!) DEMO1.LMP / Demos recorded by Doom. DEMO2.LMP < e.g. DOOM -record DEMO2 -file MYwad.wad DEMO3.LMP \ Then move DEMO2.LMP here, and that's all! DMXGUS.LMP (DOOM1) / Text file remapping MIDI instruments DMXGUSC.LMP (DOOM2) \ for the Gravis Ultra Sound card. GENMIDI Instrument mapping for GENMIDI compatible cards. *********************************************************************** Suppose you have edited ENDOOM.LMP and recorded a new DEMO1.LMP for your pwad. Just put copies of them here, and declare them in the [LUMPS] section of wadINFO.TXT like this: [LUMPS] ENDOOM DEMO1 This tells DeuTex to look here for ENDOOM.LMP and DEMO1.LMP *********************************************************************** + To replace the Heretic TITLE screens, put a 320x200 picture in the LUMPS + subdirectory and declare it as you would declare a TITLE lump. + DeuTex will know that it must convert it to the special RAW format. page 18 ---------- C) \TEXTURES ---------- NOTE: DOOM1/Heretic contains 2 Texture entries, TEXTURE1 and TEXTURE2. this is because of differences between the shareware and registered versions. If you are using DeuTex with Doom2, just ignore any references to TEXTURE2. It doesn't exist in DOOM2.wad. This subdirectory contains a text file(s) describing the Texture changes you want in your pwad (Chapter 8 describes Texture definition files). Your file can be given any name you want (prefer TEXTURE1.TXT or TEXTURE2.TXT). This name (without extension) is then entered in the [TEXTURE1] section of wadINFO.TXT. FILES PUT HERE HAVE THE EXTENSION (.TXT). THE TITLE OF ANY FILE PUT HERE MUST BE DECLARED IN THE [TEXTURE1] SECTION OF wadINFO.TXT. The file names OLDTEX1.TXT and OLDTEX2.TXT are reserved. Due to an amazing bug (in Doom?), if Doom's Texture list contains any new or redefined Textures before all the UNCHANGED Textures are listed, it produces HOM (Hall of Mirrors) errors. Previous versions of DeuTex dealt with this problem by requiring a copy of TEXTURE1.TXT (with any redefined Textures deleted) here in the \TEXTURES subdirectory. This is no longer necessary with version 3.3. DeuTex now reads the original TEXTURE1 from the main iwad while creating your pwad. It then reads your new Textures and automatically sorts , deletes, and combines all entries. Olivier's too good to you guys >;-] EXAMPLES: If you want to add ONLY new Textures: - Put your definition file here (e.g. TEXTURE1.TXT), and declare TEXTURE1 in the [TEXTURE1] section of (wadINFO.TXT). If you want to redefine Textures in TEXTURE1: - Run DeuTex -dmtextures to get the Textures. - Cut the Textures to be redefined from OLDTEX1.TXT and paste them into TEXTURE1.TXT. Edit them or change them as you wish. - You can delete OLDTEX2.TXT and OLDTEX1.TXT now if you want. - Declare TEXTURE1 in the [TEXTURE1] section of wadINFO.TXT. If you want to redefine Textures in TEXTURE2: - Run DeuTex -dmtextures to get the Textures. - Cut the Textures to redefine out of OLDTEX2.TXT and put them in TEXTURE2.TXT. Edit and change them as you wish. - You can delete OLDTEX1.TXT and OLDTEX2.TXT now if you want. - Declare TEXTURE2 in the [TEXTURE2] section of wadINFO.TXT. APPENDICES I and II contain lists of the animated and switch Textures from DOOM.wad (Not the new ones from DOOM2, sorry. Use DeuTex to make your own list). Copy the portion you want to edit into TEXTURE1.TXT. It's a little easier than hunting through the entire OLDTEX1.TXT files. Beware: some textures change a lot, between Doom and Doom2. page 19 -------------------- D) \SOUNDS and \MUSICS -------------------- + Put your new sound files here in the correct format. They must have + the same name as the sound you want to replace (Appendix IV lists the + Sound names used in Doom1 and Doom2. It also lists the sound names for + each DMAUD sound number). Put the sound NAME (no extension) in the + [SOUNDS] section of wadINFO.TXT. DeuTex uses the following formats for Doom sound files: MUSIC: (D_xxxxxx.MUS) for Doom/Doom2 (MUS_xxxx.MUS) for Heretic MUS format (RAW format, which can be created from MIDI files with MIDI2MUS.EXE, provided by ddt). SOUNDCARD SOUND EFFECTS: (DSxxxxxx.WAV) for Doom/Doom2 (xxxxxxx.wav) for Heretic Windows WAVE file (.WAV). Use a converter if you prefer .AU. Preferably use 11025 sample/second for your recording. VOC format is supported only for 11025 sample/s (DeuTex can't convert). PC-SPEAKER: (DPxxxxxx.TXT) only for Doom Text files (.TXT) with numbers 0-255 WARNING: DeuTex assumes that any file name beginning with: 'D_' or 'MUS_' is music. 'DS' is sound card sound effect. 'DP' is PC speaker sound effect. + Suppose you've created new music for Level E1M5 called D_E1M5.MUS. You + also want to replace DSSHOTGN with a your file called PTOOEY.WAV. You + would put the files here and edit your wadINFO.TXT as follows: + + [MUSICS] + D_E1M5 + [SOUNDS] + DSSHOTGN =PTOOEY + + This tells DeuTex to look here for D_E1M5.MUS and PTOOEY.WAV. + It will replace the sound DSSHOTGN with PTOOEY.WAV ---------- E) \GRAPHICS ---------- For Doom pictures other than Sprites, Flats or Textures. Put the changed Graphic FILE here in .BMP or .GIF format, and enter the NAME (without extension) in the [GRAPHICS] section of wadINFO.TXT. Suppose you have created a new TITLEPIC.BMP, and want SURRENDR.BMP to replace VICTORY2. Just put the files here and declare them in the [GRAPHICS] part of wadINFO.TXT, like: [GRAPHICS] TITLEPIC VICTORY2 = SURRENDR DeuTex will look here for TITLEPIC.BMP and SURRENDR.BMP (or .GIF). It will use SURRENDR.BMP for VICTORY2. page 20 ************ Some examples of Graphic entries in DOOM.wad ************* HELP1 The HELP screen for Doom 1.666. HELP2 Second HELP screen for Doom 1.666. HELP The HELP screen for Doom 2. TITLEPIC The title pic for Doom (320 x 200). CREDIT The credits for Doom (Don't touch!). VICTORY2 The background of the victory scenes. STCFNxx The fonts for Doom. STxxxxx Description of the status bar. M_xxxxx Description of the menus. You can read Matt Fell's DOOMSPEC for other entries, or extract them for yourself with DeuTex -graphic -xtract DOOM.wad. --------- F) \SPRITES --------- Put your new Sprites here in (.BMP) or (.GIF) format. WARNING: DOOM WILL LOCK UP IF YOU ATTEMPT TO REPLACE ONLY SOME OF THE EXISTING SPRITES! Either replace all the Sprites with DEUTEX -iwad -make or replace only some of the Sprites and use DEUSF -add, DEUSF -append or DEUTEX -merge. Suppose you want to redefine SPOSA1 and TROOB2. You want to replace them with SPOSA1.GIF and LIZARD.BMP. Put the files here, and then declare them in the [SPRITES] section of wadINFO.TXT, like: [SPRITES] SPOSA1 TROOB2 =LIZARD DeuTex will look here for SPOSA1.BMP (or .GIF) and LIZARD.BMP. ------- G) \FLATS ------- For new floors and ceilings as 64x64 (.BMP) or (.GIF) files. WARNING: TO USE YOUR NEW FLATS, YOU MUST MERGE YOUR pwad WITH THE MAIN iwad, OR USE DEUSF TO PUT ALL THE iwad FLATS INTO YOUR pwad. Sorry, but this is a limitation of Doom, not of DeuTex. Flats inserted here will not crash Doom when the pwad is run because I don't use the regular F_START F_END delimiters that confuse Doom. Your pwad *WILL* fail when it references those Flats, so heed the warning above. Suppose you want MUDDY.BMP as a new Flat, and HATCH.GIF to replace FLOOR1_7. Put the FILES here, and declare them in wadINFO.TXT, like: [FLATS] MUDDY FLOOR1_7 =HATCH DeuTex will look here for MUDDY.BMP and HATCH.BMP (Then HATCH.GIF), and replace FLOOR1_7 with HATCH.GIF. BUT, SEE WARNING ABOVE! page 21 --------- H) \PATCHES --------- The patches are the pictures that compose the textures. These pictures are often used for more than one texture. + Since DeuTex 3.6: + The patches are handled pretty much like Graphics, except that + they are to be declared in the [PATCHES] section, and the + corresponding picture put in the .\PATCHES subdirectory. + + Older versions of DeuTex didn't require you to declare your patches, + they were loaded automatically if required, but this could lead to + confusion. Now, if you want to replace an existing patch, you must + declare it explicitly. + DeuTex can guess the patches you need when it reads the textures + definitions. For compatibility with older versions, DeuTex will attempt + to load a patch from .\PATCHES if it detects that this patch is used. For every new patch that is used in the texture definitions, there must be a corresponding entry in the [PATCHES] section, and a corresponding picture file in the .\PATCHES subdirectory. EXAMPLE: Suppose you want to create a new Texture called MYDOOR, which contains two new patches called WOODEN0 and KNOB0, and a modified WARNA0 patch. The new Texture also contains the existing EXIT1 patch. FIRST: Put WOODEN0.BMP, KNOB0.GIF, and WARNA0.BMP here. THEN: Define your new Texture in TEXTURE1.TXT as shown below: MYDOOR 256 128 ; a 256x128 wall with ... * WOODEN0 0 0 ; a 256x128 background * KNOB0 64 100 ; and a small knob at (64,100) * WARNA0 128 12 ; a lite at top/center * EXIT1 128 32 ; the word exit in the center THEN: Put TEXTURE1.TXT in the \TEXTURES subdirectory. THEN: Tell wadINFO.TXT that TEXTURE1.TXT is the file containing new or modified Textures by declaring it in the [TEXTURE1] section: [TEXTURE1] TEXTURE1 THEN: Declare your new patches [PATCHES] KNOB0 WOODEN0 WARNA0 DeuTex will read TEXTURE1.TXT from \TEXTURES. TEXTURE1.TXT tells DeuTex that a new texture called MYDOOR is 256 pixels wide, and 128 pixels high. The asterisks tell DeuTex to look here for the patches WOODEN0.BMP, KNOB0.BMP, WARNA0.BMP and EXIT1.BMP. The numbers tell it where the patches go on MYDOOR. Note that WOODEN0 had better be 256x128 or bigger, or there will be at least one void column, and Doom will complain and stop. If an existing patch is called for, and no entry by that name exists here, the old patch will be used. page 22 CHAPTER 6 *************************** DeuTex Commands *************************** -------------------------- A) COMPLETE COMMAND REFERENCE -------------------------- Actually it's not complete, but those commands not mentioned here are for the Visual Basic Shell, and you'll never use them. Commands with an '*' are not implemented in the VB version. I forgot them. All optional commands must appear before non-optional ones or else they will be ignored. The Command Line Format is: DEUTEX <-optional cmd.> ,..., <-non-optional cmd.>,...,etc. + Note: since DeuTex 3.5, upper case commands are accepted. + You will generally need to type only the first 3 letter of a command. ------------- B) HELP COMMANDS ------------- -help* This one won't help you a lot, but it will give you the parameters. -syntax* Prints a short listing of the format of wad creation directives (wadinfo.txt). See the FORMATS Chapter in this manual for a more complete explanation. ----------------- C) OPTIONAL COMMANDS ----------------- -doom Use this command to indicate the directory containing DOOM.wad and DOOM.EXE or DOOM2.wad and DOOM2.EXE. If this command is not used, DeuTex looks first in the current directory for Doom. Then it looks in the current directory for DOOM2. Then it looks in the root directory of the current drive for a directory called Doom, and finally looks in the root directory of the current drive for a directory called Doom2. The first Doom it finds is used. EXAMPLE: DEUTEX -doom C:\GAMES\DOOM -dir DEFAULT IS: CURRENT DIRECTORY. This defines the working directory, into which you or DeuTex will put the wad creation directives (wadINFO.TXT). All subdirectories containing pwad parts will branch from here. The completely assembled pwad will also reside here. -deu* Use this if you want DeuTex to add 64K of junk at the end of your pwad. Why? To compensate for a bug in DEU 5.21, that makes it sometimes crash when viewing pictures. That bug is corrected in DEU 5.3. page 23 -rgb Let's you pick what *exact* color DeuTex will use for Doom's transparent color. The default is CYAN(R=0, G=255, B=255). EXPLANATION: Doom allows transparent areas in textures. Although there are 256 colors in the Doom palette, only 255 of them act as colors. Color number 247 (CYAN R=0 G=255 B=255) is used by Doom as a 'switch' to make that pixel invisible. When DeuTex imports your new graphics into a pwad, it must assign each pixel one of the Doom colors. For most of the 16 million colors possible in an RGB format such as .BMP and .GIF, it is just a matter of finding the most appropriate colors in the Doom palette to map to your graphic. However, CYAN is more of a 'switch' than a color. It wouldn't be appropriate for DeuTex to say "anything CLOSE to CYAN is transparent". That would be like saying "anything close to linedef type 39 is a teleport". Transparency is a switch, and has to be exact. Some graphics programs may not be able to meet this requirement. For example, some programs limit you to 64 (0-63) increments each in Red, Green and Blue. They multiply the result by 4 to get the true RGB value. This is fine for most purposes, but not for Doom. In any such program, the closest you can get to CYAN is, 0 for Red, 63 for Blue and 63 for Green. When multiplied to get a true RGB value, this becomes R=0, G=252,B=252. You couldn't tell the difference by looking, but DeuTex can. It will take this value and say "Hmmm... Light Blue". Your graphic will be disappointing when you see it in Doom :-< -rgb 0 252 252 will make you smile again :-) Another example of when you might want to use this command is if you use a raytracer to create your graphics. Most of these programs render the background as black. If you use the option -rgb 0 0 0, things will be much easier. -bmp File format to use when EXTRACTING pictures. DeuTex will -gif recognize either one when STORING pictures in a pwad. The -ppm DOS version defaults to .BMP; the UNIX version defaults to .GIF. Avoid the 24bit BMP format! Use 8bit (256 color) and have the color quantization done by a serious program. Mine works if you need it, but it's lame. See "What are the Palettes For?" in Chapter 1. -wave File format to use when EXTRACTING sounds (DeuTex will -au recognize either one when INSERTING sounds). The DOS -voc version defaults to .WAV; the UNIX version defaults to .AU. -fullsnd When extracting a sound from a wad, causes DeuTex to extract everything the lump contains instead of just the number of samples indicated in the lump header. -rate Tells DeuTex what to do when asked to compose a wad from sound files whose sample rate is not 11,025 Hz. The argument can take the following values: reject consider it a fatal error force emit a warning and force the sample rate to 11,025 Hz by crudely resampling up or down warn emit a warning (it's the default) accept don't even warn Prior to version 4.5, the policy was always "force" because the original Doom did not support anything else. Today, as most engines support mixed sample rates, it makes sense to be more relaxed about it. However, even some recent engines still have limitations; for example, XDoom and LxDoom play all sounds at 11,025 Hz, regardless of their actual frequency and it has been reported that PrBoom has trouble with sample rates that are not whole multiples of 11,025 Hz. That's why the default policy is not "accept". Matthew Miller should take credit for bringing all the above to my attention. Note that this option only takes effect when composing a wad. When decomposing, DeuTex always saves sounds verbatim. page 24 -levels These tell DeuTex to select Sprites, patches, sounds, etc. -lumps when composing/decomposing/merging pwads. These commands -textures can be combined. By default, all entries are selected. -sounds -musics -graphics -sprites -patches -flats -sneas -sneaps -sneats -iwad To be used with -make, this command makes an iwad instead of a pwad. This is necessary if you are building a pwad which contains all the Sprites and/or all the Flats. This enables you to rebuild the DOOM.wad if really needed. -------------------------------------- D) COMMANDS TO COMPOSE OR DECOMPOSE pwads -------------------------------------- -wadir Directory list, with entry identification. Exact entry identification is sometimes impossible in a pwad. In that case, Sprites, Flats or patches might be reported as Graphics. -xtract -extract Will extract Lumps, Graphics, Flats, patches, Sprites, sounds and Levels from a wad and put them into a subdirectory having the same name (all .LMPs in \LUMPS, etc). Also lists any Texture entries of the wad in a file called TEXTURE1.TXT, which it puts in a subdirectory called \TEXTURES. If you are extracting the main DOOM1 wad, a second Texture file, TEXTURE2.TXT will be extracted. DOOM2 does not have a TEXTURE2 entry. If a given subdirectory does not exist, it will be created. Also creates the file wadINFO.TXT in the working directory. The working directory is the directory the command is entered from unless -dir is used to specify one. See the Chapter 8 - FORMATS for a description of wadINFO.TXT, TEXTURE1.TXT and TEXTURE2.TXT. This command will not overwrite already existing entries. It will complain and stop instead. -get Will retrieve the entry called as picture, sound or lump, from . if is unspecified this default to the main wad. This is no more than an emulation of DMGRAPH/DMAUD. + -usedtex + + This command will scan the level files in the pwad, and report + all the texture names that are affectively used. + Use this when you convert pwads from Doom to Doom2 or Heretic + so as to know which texture you really need. page 25 page 25 -make -build -create Reads wadINFO.TXT and uses it to compose MYOWN.wad from the files in the subdirectories. See FORMATS for a description of wadINFO.TXT. MYOWN.wad will be created in the current directory. If it already exists, it WON'T be overwritten, so it must be deleted or moved to create a new version. This command replaces DMGRAPH, DMMUS, DMTEX and DMAUD. (DMAUD recognises more formats than .WAV and .AU, but it doesn't work with Doom v1.666 or Doom2). + -s_end + This switch is only related to an ugly trick with sprites. + This special switch shall be placed *before* -make when + you want to build a special sprite pwad. Such a pwad require + that you patch the game executable, so it's not for newbies. + Don't use that switch unless you really mean it. -check Will look for any Textures defined in MYOWN.wad which contain void columns that would crash Doom. Use this after modifying Textures (Similar to the way you use checks in DEU). + It will also report the textures that cannot be used in a + Two sided wall (a medusa effect would happen if you used them). -unused Checks for unused bytes in a pwad. Reports all the unused zones, total number of byte wasted, and the repartition depending on size of wasted areas. --------------------------------------------- E) COMMANDS FOR MERGING pwads INTO THE MAIN iwad --------------------------------------------- -merge Will put the entries of MYOWN.wad into the main Doom.wad file, thereby removing all restrictions Doom puts on pwads. This is much safer and much cleaner than inserting or restoring entries with DMGRAPH or such, but your iwad IS modified. Usually used for Sprites and Flats. -restore Will restore DOOM.wad and the merged MYOWN.wad. To be used after the -merge command, to undo the job. Files are reconstructed using information stored in the iwad at the time the -merge is done. -join + Will join two pwads: mysecond.wad is put inside myfirst.wad. + Great for combining pwads! + If entries are duplicated, mysecond.wad has priority + If custom textures are defined in both wads, they are + preserved, but those of mysecond.wad have priority. page 26 -app + Appends all sprites and flats to a pwad. + this is necessary before a pwad defining custom sprites and + Flats is used with Doom. Doesn't work with Heretic 1.0, + but it should... another bug of Heretic... + -as + Same as -sprites -app. Appends only Sprites. + (-as does the same thing as the corresponding NWT command) + -af + Same as -flats -app. Appends only Flats. + (-af does the same thing as the corresponding NWT command) -add Same thing as -app, but mysprite.wad is not modified. final.wad is generated instead. Avoid this, it waste space. (this is only for compatibility with the old DMADDS tool). SAFEGUARD: - ONLY 8 BYTES of DOOM.wad are modified - If all else fails, you can restore your iwad by hand. - Only about 32k of additional disk space are needed. - MYOWN.wad is put INTACT into DOOM.wad. It can then be deleted since -restore recreates it. This is barely a modification at all! How does it work? - Restoration information is added at the end of the iwad. - Then the pwad is pasted intact at the end of the iwad. - The iwad directory is rebuilt (about 32K) and appended. - The pointer to the Doom directory is modified (8 bytes). After all that mess, a directory entry called _DEUTEX_ is added. it is of no use for Doom/Heretic, and is just ignored. But if you modify your wad with some other tool, this entry will still point to the restoration information, enabling DeuTex to salvage the wad. I did my best to make this command the safest possible. I have tested this command thoroughly and believe it can be trusted. Be aware, however, that the resulting iwad might not work with Doom if the included pwad does not respect some conventions about Sprites and Flats. If this happens, the files are still safe, just -restore them. The conventions a pwad must follow are: -There must be F_START or FF_START before the first Flat. -There must be S_START or SS_START before the first Sprite. Sorry, but there is NO OTHER WAY if we want to be able to add new Sprites and Flats that are unreferenced in DOOM.wad. It would be vain to compare the sprites names with those of the iwad, because it's DOOM.EXE that determines which sprites are which, not the iwad. And as DOOM.EXE can be hacked, and sprites vary with versions of Doom, there is really no other choice. page 27 CHAPTER 7 *************************** DeuSF Commands **************************** -------- A) OVERVIEW -------- DeuSF is an improved replacement for DMADDS. It adapts to all versions of Doom, requires a less perverted pwad structure, and can append to a pwad rather than generating a new pwad (thereby saving space). DeuSF works with pwads composed for DMADDS, and should work for ones composed for DMADDF. Of course, the PREFERRED pwad composer for DeuSF is DeuTex! + The code for DeuSF is 100% the same as that of DeuTex. + All the commands of DeuSF are the same as the DeuTex equivalent, but + since DeuSF is smaller, it's more suitable for distribution. DeuSF need only be applied to pwads that contain: -some Sprites to replace those of DOOM.wad. -some Flats to replace those of DOOM.wad. DeuSF need NOT be used if: - the pwad contains *all* the Sprites of DOOM.wad - the pwad contains *all* the Flats of DOOM.wad - the pwad contains Sprites which are not referenced in DOOM.EXE. (a DeHacked patch is needed to have them work) DeuSF can only be used on pwads that respect a precise format: - Sprites are identified only if comprised between: S_START or SS_START and S_END or SS_END -Flats (floor/ceilings) are identified only if they occur between: F_START or FF_START and F_END or FF_END If this format is NOT respected, DeuSF might fail to identify entries correctly. This is because in iwad and pwad entries there is nothing internal to a Sprite or Flat that identifies it as such. This format is generated by DeuTex automatically, and is compatible with DMADDS. DeuSF is meant to be distributed with your pwad, so it has no restrictions on distribution (Unlike DeuTex, see License Section). This lets you send DeuSF with your pwad, along with a batch file like the one in the following example. Your pwad contains new Sprites and Flats, but not all of them. Your batch file might read: DeuSF -app mywad.wad DOOM -file mywad.wad -warp x x DeuSF -res mywad.wad First, DeuSF appends the Sprites and Flats from DOOM.wad to mywad.wad. Then the pwad is played. The last command deletes the appended Sprites and Flats from mywad.wad, restoring it to it's original condition. This kind of pwad should PREFERABLY be built with DeuTex. page 28 An example of DeuSF usage on ALIENDOOM 2.2: DeuSF -doom c:\doom -sprite -add ALIENGFX.wad ALINGRFX.wad DeuSF reads ALIENGFX.wad to find what Sprites are missing. It then extracts them from DOOM.wad and creates a new pwad, ALINGRFX.wad from the original pwad and the extracted Sprites. DOOM.wad and the original ALIENGFX.wad are unchanged. Even better: DeuSF -doom c:\doom -sprite -app ALIENGFX.wad > aliengfx.log DeuSF reads ALIENGFX.wad to find what Sprites are missing. It then extracts them from DOOM.wad and appends them to ALIENGFX.wad. DOOM.wad is unchanged. If -res doesn't work for any reason, ALIENGFX.wad can be restored by hand from the information in aliengfx.log You *should* take the time to evaluate this tool even if you're not convinced at all. Trust that this time won't be wasted. DeuSF -join, -merge, -app, -res commands are incredibly more powerful than those of DMADDS. NWT duplicate some of the features of DeuSF, but isn't par to DeuSF (as of NWT version 1.03). Great care involved in designing those DeuSF functions, and DeuSF in not only the most powerful, it's also the only one ported to other O/S. Let me insist that you should use DeuSF to install your wads. -------------------------- B) COMPLETE COMMAND REFERENCE -------------------------- All optional commands must appear before all non-optional ones. Otherwise, they are ignored. Command Line Format: DeuSF ,...,,...,etc. ******** 1) HELP COMMANDS -help Lists these parameters. -format Displays a summary of the format conventions a pwad must follow so that DeuSF can recognize Sprites and Flats properly. -wadir Scrolls the entries in the pwad directory down the screen, along with what type DeuSF thinks each entry is (Sprite, Flat, Graphic, etc.). For a pwad with many entries, you may want to pipe this command (i.e. DeuSF -wadir | more) to ease readability. Used to check if DeuSF recognises all the entries correctly, for instance when there is a problem with -app or -add. page 29 ******** 2) OPTIONAL COMMANDS -doom Use this command to indicate the directory containing the DOOM.wad and DOOM.EXE you want to use. See the description in the DeuTex command reference for default information. For example: DeuSF -doom C:\GAMES\DOOM -sprite Use with -add or -app, to add only Sprites or only Flats. If -flat neither of these commands is present, DeuSF will add both. ******** 3) MANDATORY COMMANDS (one of these will always be used) -add (same as in DeuTex) Will create a new file, ALLSF.wad, containing all the Sprites and/or Flats of DOOM.wad together with those contained in MYOWN.wad. This is exactly like DMADDS ...but cleaner. -app (same as in DeuTex) Will append to MYOWN.wad only those Sprites and/or Flats of DOOM which are not redefined. This saves disk space, compared to -add command. -join Will append to THIS.wad all the Sprites and Flats contained in THAT.wad. This function enables you to merge two Sprite and/or Flats pwads obtained from different sources. I added this command so that I could play CHOOK and BARNEY together. TEXTURES and PNAMES entries of both THIS.wad and THAT.wad. If entries are conflicting, those of THAT.wad have priority. Avoid conflicts! -join is not really clever. NOTE: After using -join on pwads, you still have to use -app on the combined pwad to append the remaining Sprites and Flats from Doom. -res (same as in DeuTex) Restores a pwad which had been modified with -app command. Quite safe. Performs the same function as -restore in DeuTex. If a pwad was merged inside another one (using -join), then that pwad regenerated also. Now *that's* real cool! page 30 CHAPTER 8 ******************************* FORMATS ******************************* ---------------------------- A) The wad Creation Directive wadINFO.TXT ---------------------------- ******** 1) OVERVIEW The creation directive file is used by the DeuTex -make command to compile a pwad containing all of the desired enhancements. It is automatically generated by the -xtract command and placed in the working directory (e.g. MYwad\). You can rename this file whatever you like, and reference it when you use the -make or -merge commands. + The file lists most of the entries which will be present in the pwad + file (with the exception of PATCHES and PNAMES, see note below). It is + structured similarly to a Windows .ini file with sections headed by + names enclosed in brackets.It contains up to 7 sections: [LEVELS], + [LUMPS], [TEXTURE1], [SOUNDS], [GRAPHICS], [SPRITES] and [FLATS]. + For DOOM1, there can be an eighth section called [TEXTURE2]. + + All sections are optional. Starting with DeuTex version 3.0, the order + of the sections is not critical. The name of the section IS critical, + and must be spelled correctly. NOTE: There is no [PATCHES] section. Patch loading is automatic. If a new patch is referenced in a Texture, DeuTex will look for it in \PATCHES. If there is a patch in \PATCHES with the same name as an existing patch, DeuTex will automatically find it and load it. There is no need to reference a redefined patch in a Texture definition, unless it is part of a new or redefined Texture. There is also no need to define PNAMES. PNAMES creation is automatic. The names TEXTURE1 and TEXTURE2 refer to the OLDTEX1.TXT and OLDTEX2.TXT files as extracted from Doom. Unlike previous versions, DeuTex doesn't need these files. They exist only for you. They are useful in examining the makeup of textures in the wad. They also make redefining existing Textures easier by allowing you to cut and paste instead of typing the redefined Texture from scratch. DeuTex 3.3 takes all the information on existing Textures directly from the main wad while building your pwad. Any new definitions supplied by you will override those in Doom. A warning will be given to inform you of this. This is a great improvement and makes DeuTex even easier than before! Previous versions of this manual also generated confusion over where, how, and if you need to use OLDTEX2.TXT (then named TEXTURE2.TXT) The short answer from now on is: NOWHERE, NOHOW and NO! Since DeuTex 3.1, [TEXTURE1] and [TEXTURE2] are separate sections. There is ONLY ONE case where you will use [TEXTURE2]. This is when you are using Doom1 and you redefine a TEXTURE2 Texture. OLDTEX2.TXT does NOT need to be present, even in this situation. Use it for your edits. If your pwad is for Doom2, or is for Doom1 and doesn't change any TEXTURE2 Textures, IGNORE all references to TEXTURE2 in this document! page 31 ******** 2) EXACT FORMAT for wadINFO.TXT The following pages show the exact format for all the entries in a pwad Creation Directive File (i.e. wadINFO.TXT or YOURNAME.TXT). All main sections are optional. Order of sections is unimportant. The Symbols used in the Format Listing are as follows: SYMBOL DEFINITION _______________________________________________________________________ | | | | x and y | Numbers for offsets, levels, etc. | |________________________|____________________________________________| | | | | aaaa, bbbb and cccc | YOUR name for a given item (8 char max). | |________________________|____________________________________________| | | | | qqqq, rrrr and ssss | VARIABLE parts of a Doom name. | |________________________|____________________________________________| | | | | CAPITAL LETTERS | MANDATORY parts of an entry. | |________________________|____________________________________________| | | | | Doom name '=' aaaa | DeuTex will insert 'aaaa' as 'Doom name'. | |________________________|____________________________________________| | | | | brackets [ ] | Define main sections in the file. | |________________________|____________________________________________| | | | | parentheses ( ) | These entries are optional. | |________________________|____________________________________________| | | | | asterisk '*' | Reuse the resource from the previous line. | |________________________|____________________________________________| | | | | dot+comma ';' | 'Comment' follows. (Windoze standard) | | pound sign '#' | 'Comment' follows. Rest of line ignored. | |________________________|____________________________________________| | | | | 'white space' (spaces) | Ignored by DeuTex. | |________________________|____________________________________________| page 32 Listing of the Format for wadINFO.TXT: ; ; DeuTex by Olivier Montanuy ; ; pwad creation directives ; ; [LEVELS] ; Section to define the Level of your map(s). ; MAPnm (=aaaa) ; If '=aaaa' and '=bbbb' are used, looks in \LEVELS for EnMm (=bbbb) ; aaaa.wad and bbbb.wad. If '=aaaa' and '=bbbb' are not ; used, looks in \LEVELS for MAPnm.wad and EnMm.wad. ; Combines them into one pwad containing MAPnm and EnMm ; ; DeuTex does not care about the internal Level of ; aaaa.wad or MAPnm.wad. It will output the pwad as ; whatever MAPnm or EnMm is put here. Easy conversion. ; ; EnMm can be E1M1 thru E3M9. ; MAPnm can be MAP01 thru MAP35. ; MAPS 33, 34 and 35 will play, but can only be entered ; by IDCLEV. An EXIT LEVEL switch on 33, 34 and 35 will ; just return you to DOS. ; ; If EnMm and MAPnm are entered in the same pwad, EnMm ; will play from Doom1 and MAPnm will play from Doom2, ; IF there are no Texture additions to the pwad. It is ; still possible with Textures, but is a can of worms, ; and you'd better know what you're doing. ; ; Thus, it is possible to make a 62 Level pwad with ; DeuTex, although some imagination would be needed to ; overcome the limitations of Levels 33, 34 and 35 in ; Doom2, and only about half the wad would be available ; to each Doom engine. This may be useless, but since ; it's possible, it is included here. ; ; [LUMPS] ; Section to define any .LMP data you want to add. ; Chapter 5, Section B) describes Lumps. ; qqqq (=aaaa) ; If '= aaaa' is used, looks in \LUMPS for aaaa.LMP. If ; '= aaaa' is not used, looks for qqqq.LMP. Installs the ; .LMP data in the pwad to replace qqqq in Doom. ; rrrr (*) ; If '*' is used, .LMP from the previous entry is used ; for this entry as well. When you play the pwad, qqqq ; will be used for both qqqq AND rrrr. ; ; page 33 [TEXTURE1] ; Section for declaring what Texture definition files you ; want to use when compiling your pwad. ; aaaa ; First loads TEXTURE1 from the main Doom or Doom2 wad. (bbbb) ; Then looks in \TEXTURES for aaaa.TXT. Compiles your pwad (cccc) ; Texture directory by: TEXTURE1 - (redefined Textures in ; aaaa.TXT)+(ALL textures in aaaa.TXT) = TEXTURE1 in pwad. ; ; If 'bbbb' and 'cccc' are used, DeuTex searches for ; bbbb.TXT in \TEXTURES, RE-edits the TEXTURE1 entry using ; it, then gets cccc.TXT and repeats the process. This ; means that if any duplicate Texture names exist in aaaa, ; bbbb and cccc, only the entry from the last file listed ; will be present in the final pwad. ; [TEXTURE2] ; Used only for Doom1. Shows what Texture definition aaaa ; file(s) to use for TEXTURE2. Similar to above. ; ; [SOUNDS] ; Section to define your modified sound entries. ; DSqqqq (=aaaa) ; If '=aaaa' is used, looks in \SOUNDS for aaaa.WAV ; (sound effect). If '= aaaa' isn't used, looks for ; DSqqqq.WAV. Uses file to replace Doom sound DSqqqq. ; DPqqqq (=aaaa) ; If '=aaaa' is used, looks in \SOUNDS for aaaa.TXT ; (PC Speaker sound). If '= aaaa' is not used, looks ; in \SOUNDS for DPqqqq.TXT. Uses file to replace ; Doom PC Speaker sound DPqqqq. ; D_qqqq (=aaaa) ; If '=aaaa' is used, looks in \SOUNDS for aaaa.MUS ; (Music file in Doom's .MUS format). If '=aaaa' is ; not used, looks for D_qqqq.MUS. Uses file to replace ; Doom Music D_qqqq. ; D_rrrr (*) ; If '*' is used, the sound from the previous entry is ; used for this entry as well. In this example, when ; you play your pwad, D_qqqq will be used for both ; D_qqqq AND D_rrrr. ; ; [GRAPHICS] ; Section used to declare Graphics other than ; Sprites, Flats, or Textures. See Chapter 5, ; Section E) or Matt Fell's Doom specs for a ; description of Graphic entries in Doom. ; qqqq (xx)(yy) (=aaaa) ; If '=aaaa' is used, looks in \GRAPHICS for ; aaaa.BMP. If not found, looks for aaaa.GIF. ; If '=aaaa' is not used, looks for qqqq.BMP ; or .GIF. Inserts the file in pwad for entry ; qqqq. xx and yy are the horizontal and ; vertical offsets used when inserting the ; Graphic into it's defined area. The defined ; defined area is predetermined by DOOM.EXE ; from the Graphic name. ; page 34 ; For example, all Graphics beginning with STF ; are placed in a box 31 x35 pixels big at the ; center of the Status Bar. This is where the ; player's face shows up. The xx and yy values ; move the Graphic around in this box. Positive ; values move it left (xx) and up (yy). ; rrrr (*) ; If '*' is used, will re-use the Graphic from ; the previous line for rrrr too. ; ; [SPRITES] ; Section used to declare Sprites. Consult the ; following for more information on modifying ; Sprites in Doom: ; Chapter 3 - Section C) ; Chapter 5 - Section F) ; Chapter 6 - Section E) ; Chapter 7 - All Sections ; qqqq (xx)(yy) (=aaaa) ; If '=aaaa' is used, looks for aaaa.BMP or ; .GIF in \SPRITES. If '=aaaa' is not used, ; looks for qqqq.BMP or GIF. Inserts the file ; into the pwad to replace the Sprite qqqq. ; rrrr (*) ; '*' tells DeuTex to use the previous entry ; (qqqq) for this Sprite as well. ; ; [FLATS] ; Section for declaring modified Flats. Limitations ; are similar to the ones for modifying Sprites. See ; [SPRITES] section above for places to find info. ; qqqq (=aaaa) ; If '=aaaa' is used, looks for aaaa.BMP or .GIF in ; \FLATS. If '=aaaa' is not used, looks for qqqq.BMP or ; .GIF. Inserts file into pwad as replacement for qqqq. ; ; There are no insertion points for Flats, since they ; all MUST be 64x64. ; ; ; End File. page 35 ******** 3) An EXAMPLE LISTING of wadINFO.TXT The following is a commented example of pwad creation directives, A space or any text after a ';' or '#' to the end of a line is ignored. Not all entries need be present, and order of [SECTIONS] is optional. ************************ wadINFO.TXT ***************************** ; ; The [LEVELS] section defines the Doom1 Levels and Doom2 maps. ; [LEVELS] E1M2 ;file loaded: LEVELS\E1M2.wad MAP04 ;file loaded: LEVELS\MAP04.wad E2M3 =TRINITY ;file loaded: LEVELS\TRINITY.wad ;if more than one Level, E2M3 is read ; ; All .wads referred to here must contain the 11 entries that ; define a Level, including NODES, BLOCKMAP and REJECT. Use ; IDBSP and RMB to build them. ; ; The [LUMPS] section defines the Lumps of raw data for Doom. ; [LUMPS] ENDOOM ;file loaded: LUMPS\ENDOOM.LMP DEMO1 ;file loaded: LUMPS\DEMO1.LMP DEMO2 =KILLJOHN ;file loaded: LUMPS\KILLJOHN.LMP ; ; See Directory Structure - LUMPS\ for a precise description of all ; these entries. Apart from the DEMO or possibly ENDOOM, there is no ; real need to mess with them. DEMOs can be recorded by DOOM. ; ; The [TEXTURE1] section lists the names of the Texture definition files ; from \TEXTURES that are to be used for TEXTURE1. ; [TEXTURE1] ;DeuTex will first read TEXTURE1 in DOOM.wad ; TEXTURE1 ;file read: \TEXTURES\TEXTURE1.TXT MYWALLS ;file read: \TEXTURES\MYWALLS.TXT MYSWITCH ;file read: \TEXTURES\MYSWITCH.TXT ; ; The new Textures found in these files are placed at the end of the ; Texture list. If they have the same name as an entry in OLDTEX1, ; (that is: the old Doom texture) then that entry is deleted. ; ; The [TEXTURE2] entry is not needed for Doom2 ; [TEXTURE2] ;DeuTex will first read TEXTURE2 in DOOM.wad. ; TEXTURE2 ;file read: \TEXTURES\TEXTURE2.TXT ; ; The new Textures found in this file are placed at the end of the ; Texture list. If they have the same name as an entry in TEXTURE2, ; that entry is deleted. ; ; BEWARE: don't duplicate TEXTURE1 entries in TEXTURE2. ; Doom Doesn't care, but it crashes some Level ; editors. ; page 36 ; The [MUSICS] section defines MUSIC ; D_E2M3 ;file loaded: SOUNDS\D_E2M3.MUS (doom1 music). D_RUNNIN ;file loaded: SOUNDS\D_RUNNIN.MUS (doom2 music). D_ROMERO * ;no file loaded! The '*' copies D_RUNNIN to D_ROMERO. ;now Doom will think D_ROMERO=D_RUNNIN. D_SHAWN3 =KATEBUSH ;file loaded: SOUNDS\KATEBUSH.MUS. ;The music for SHAWN3 will be KATEBUSH. ; ; D_E2M3 is the music for Episode2 Mission 3 of Doom. ; In Doom2, it's a real mess. The Music name is not related ; to the Level name, but to the guy who made the Level. ; MUS format can be obtained from MIDI with MIDI2MUS, or ; converted back to MIDI by MUS2MIDI (by just_joe). ; These are separate utilities (too technical for DeuTex) ; ; The [SOUNDS] section defines PCSOUNDS and WAVE SOUNDS ; [SOUNDS] DSSLOP ;file loaded: SOUNDS\DSSLOP.WAV, .AU or .VOC DSPISTOL =BOIING ;file loaded: SOUNDS\BOIING.WAV, .AU or .VOC ;this is a WAV sound, meant for sound cards. ; DPSLOP ;file loaded: SOUNDS\DPSLOP.TXT ;this is a PC speaker sound. ; ; The WAV, AU and VOC format were hacked. ; DeuTex can't read compressed data. ; The format PC-speaker sound is a list of integers ; (range 1-255). related to sound pitch... ; ; ; The [GRAPHICS] section defines all the fixed pictures. ; (Not Sprites, patches, or Flats) ; [GRAPHICS] WIMAP1 ;file loaded: GRAPHICS\WIMAP1.BMP. STHURT1 23 45 ;file loaded: GRAPHICS\STHURT1.BMP. ;set the insertion point to 23,45. STHURT2 * ;Doom will use STHURT1 for STHURT2. VICTORY2 0 12 =SULACCO ;file loaded: GRAPHICS\SULACCO.BMP ;set the insertion point to 0,12. ;SULACCO.BMP will now replace VICTORY2. ; ; Fixed pictures include: opening screen, ; texts (!), menus, status bar, ending pictures ... ; You can only use names already defined in Doom. ; Otherwise Doom will ignore them. (you'll be warned :-) ; ; This section declares the Sprites. ; [SPRITES] BOSSB1 ;File loaded: SPRITES\BOSSB1.BMP or .GIF ;calculate insertion point by itself. BOSSA1 10 20 ;File loaded: SPRITES\BOSSA1.BMP or .GIF ;set the insertion point to 10,20. BOSSA2A8 * ;DeuTex will set BOSSA2A8 equal to BOSSA1 VILEA1 30 40 =BILLGATE ;File loaded: SPRITES\BILLGATE.BMP or .GIF ;VILEA1 will now be BILLGATE.BMP page 37 ; If you redefine ALL sprites, use the -iwad option. ; Otherwise, you'll have to use DeuSF to rebuild a complete Sprite pwad ; each time the wad is played. This is because of a limitation of Doom ; which still has not been removed (ask Id software about it). ; ; ; Don't declare your patches. ; A patch, say xxxx, will automatically be loaded into ; the pwad from the file PATCHES\xxxx.BMP (or .GIF) if: ; ; 'xxxx' is referenced in one of the Texture files, as a patch. ; or 'xxxx' exists as a patch in the original Doom. ; ; ; ; The [FLATS] section declares the Floors and Ceilings ; [FLATS] GRASS ;file loaded: FLATS\GRASS.BMP (or .GIF) HERBE * ;Doom will think HERBE is the same as GRASS BLOOD1 = MUDDY ;file loaded: FLATS\MUDDY.BMP ; All these files must be 64x64 pixel pictures. ; ; You can define new Flat names, or redefine existing Flats, but unless ; you redefine the complete list of Flats, and use the -iwad option, you ; need to use DeuSF to rebuild the complete Flat list whenever you want ; to use the pwad. ; ; ; wad creation directives end here. ; page 38 ----------------------------------- B. The Texture Definitions Text File \TEXTURES\MYTEXT.TXT ----------------------------------- ******** 1) OVERVIEW Some Notes on Texture definitions: - READ the DOOM SPECS by Matt Fell. - You can create Textures for transparent walls (see DeuTex Commands -rgb), but make sure that they're composed of only one patch. Otherwise, you'll get the Medusa Effect. - Avoid using a Texture less than 128 pixels high on a wall higher than the Texture (Tutti Frutti effect). - Texture widths should be rounded to the next power of 2. (8,16,64,128,256,512,1024 are usable) - Patches composing Textures can not be more than 320 pixels wide. - Doom will ignore any portion of Textures higher than 128 pixels. - You can create a non repeating sky Texture: Define the SKY1 (or SKY2, SKY3, RSKY1, RSKY2, RSKY3) entry as a 1024x128 area cover it with patches. Note that SKY patches appear horizontally inverted. 0=east, 256=north, 512=west, 768=south. - Make sure all Textures are completely covered by patches. Otherwise, Doom will puke (void column error). - You can create animated walls with (almost) any sequence of pictures. No known limit in the number of frames (27 is OK!). The way to do this is: Edit the Textures of one of Doom's existing animated walls (beginning and end). Use the original names for these entries. They are coded into DOOM.EXE. Add the other frames for your animation between these entries in your Texture list. - READ the DOOM SPE.... Well, you get the picture >;-{]> Once you have created a new pwad, check it with the -check command. DeuTex will complain if: - Any Texture width is NOT a power of 2 (2,4,8,16,32,64,128,etc). (Doom will round to the next lower power of 2) - Any Texture height is greater than 128. (Doom ignores everything above 128) - Any Texture is not completely covered by patches. (Doom will exit with a void column error) - A Level tries to use of an undefined Texture. A Texture entry consists of: (Texture Name) (WIDTH) (HEIGHT) * (Patch1) (X offset)(Y offset) * (Patch2) (X offset)(Y offset) * (Patch3) (X offset)(Y offset) . . . . . . . . . . . . * (PatchN) (X offset)(Y offset) This format is supported by both New Wad Tool and the Visual Basic shell for DeuTex, so use the one you prefer, to build your Textures. page 39 Texture names are 8 characters or less. Width and Height are in pixels. An asterisk '*' identifies the following word as a PNAME. Patch names are 8 characters or less. X and Y offsets are pixel measurements. Offsets are measured from upper-left corner (0,0). X = positive. Offset patch to the right. X = negative. Offset patch to the left. Y = positive. Offset patch down. Y = negative. Offset patch up. The following figure is a feeble attempt to illustrate this: _______________________ | | ^ | PATCH 1 | | | Both x and y | Y | have negative | | | offsets. _______|_v_______________________________________ | | | ^ | ^ | | | | TEXTURE | | | | | | | | | | | Y | | | | | | | | |_______________|_______| | | H | __v_______________________ | E <----- X ----->| | | | I | | PATCH 2: | | G | | Both x and y have | | H |<------- X ------->| positive offsets. | | T | | | | | | | | | | | | | | | | |__________________________| | | | | | |_________________________________________________| v <-------------------- WIDTH ---------------------> TEXTURE DEFINITION SHOWING PATCH OFFSETS page 40 ******** 2) An EXAMPLE LISTING of MYTEXT.TXT Texture Definition File Example *************************** TEXTURE1.TXT ****************************** ; ; Anything following a ';' or ';' is ignored (comment). ; ; An asterisk '*' at the beginning of a line indicates a patch. ; ; ASHWALL is a Texture 64 pixels wide, and 128 pixels high. ; It contains only one patch, W104_1, with no offset. ; ASHWALL 64 128 * W104_1 0 0 ; ; BIGDOOR7 is a Texture of size 256x128 (X size, Y size) composed of two ; patches, W105_1 and W105_1 placed at offset -4,-4 and offset 124, -4. ; BIGDOOR7 256 128 * W105_1 -4 -4 * W105_1 124 -4 ; ; FLOWER is a new Texture (didn't exist in DOOM.wad). ; It is composed of an old patch. ; FLOWER 32 128 * TP5_1 0 0 ; ; BLODGR2 redefines the old BLODGR2 Texture ; to be composed of the new patch BIRDY ; BLODGR2 34 128 * BIRDY 0 0 ; ; A new Texture, HADDOCK, composed of new and old patches. ; HADDOCK 64 128 * FISH1 0 0 * BIGFISH 23 44 * TP5_1 0 0 ; ; Example of wall animation. ; ; Start with the first entry of an existing animation (FIREBLU1). ; Insert additional entries as needed for your animation (ZZZ...). ; End with the closing entry of the existing animation (FIREBLU2). ; When FIREBLU1 is used in your pwad, it will have your animation! ; Notice that the example uses sprites as patches. Doom don't know ; and Doom don't care! ; FIREBLU1 128 128 ;First frame is a redefined * WALL62_1 0 0 ;Doom animated Texture. These * BOSSA1 83 47 ;are called in the DOOM.EXE. * GOR2A0 20 -70 ZZZA 128 128 ;Frame 2 inserted. * WALL62_1 0 0 * BOSSB1 75 47 * GOR2A0 20 -50 page 41 ZZZB 128 128 ;Frame 3 inserted. * WALL62_1 0 0 * BOSSC1 71 47 * GOR2A0 20 -35 ZZZC 128 128 ;Frame 4 inserted. * WALL62_1 0 0 * BOSSD1 61 47 * GOR2A0 20 -25 ZZZD 128 128 ;Frame 5 inserted. * WALL62_1 0 0 * BOSSF1 47 47 * GOR2A0 20 -20 ZZZE 128 128 ;Frame 6 inserted. * WALL62_1 0 0 * BOSSE8 54 47 * GOR2A0 20 -17 ZZZF 128 128 ;Frame 7 inserted. * WALL62_1 0 0 * BOSSE7 68 47 * GOR2A0 20 -16 ZZZG 128 128 ;Frame 8 inserted. * WALL62_1 0 0 * BOSSE6 64 47 * GOR2A0 20 -17 ZZZH 128 128 ;Frame 9 inserted. * WALL62_1 0 0 * BOSSF5 60 47 * GOR2A0 20 -20 ZZZI 128 128 ;Frame 10 inserted. * WALL62_1 0 0 * BOSSF4 63 47 * GOR2A0 20 -25 ZZZJ 128 128 ;Frame 11 inserted. * WALL62_1 0 0 * BOSSD2D8 64 47 * GOR2A0 20 35 ZZZK 128 128 ;Frame 12 inserted. * WALL62_1 0 0 * BOSSB1 68 47 * GOR2A0 20 -50 ZZZL 128 128 ;Frame 13 inserted. * WALL62_1 0 0 * BOSSC1 70 47 * GOR2A0 20 -70 FIREBLU2 128 128 ;Fourteenth Frame is an * WALL62_1 0 0 ;edited FIREBLU2, which is * BOSSB1 73 47 ;the last frame of the * GOR2A0 20 -64 ;Doom animated Texture. ; ; End of example ; ; ; file ends here. bye! page 42 --------------------------- *** [PART THREE] ALL THE REST *** --------------------------- CHAPTER 9 *************************** NECESSARY STUFF *************************** ------------------------------ A) DeuTex/DeuSF License Agreement ------------------------------ See LICENSE. page 43 ----------- B) Legal Stuff ----------- See LICENSE. page 44 ------------------------- C) Where to get DeuTex/DeuSF ------------------------- The primary site for DeuTex is http://www.teaser.fr/~amajorel/deutex/ DeuTex and DeuSF are meant to be available by anonymous FTP on Internet sites: the same as of those of DEU: ftp.cdrom.com,ftp.luth.se,iglou.com,... /pub/doom/utils/graphics_editing/deutex DeuTex and DeuSF are available on Compuserve, by special request of Dr. Sleep: GAMERS FORUM LIB 8 ACTION GAME AIDS [CIS:GAMERS] PC WORLD FORUM LIB 22 The DOOM ROOM [CIS:PWOFORUM] You might also want to try: WinTex The graphic interface for DeuTex NWT by Denis Moeller A very good DOS Tool, easy to use. ideal for making small changes to a wad. unsuitable for handling large set of entries. Texture text format is compatible with DeuTex. DOOMTEX by Steve McCrea A list of tools to generate Textures. It's not exactly user friendly, but successfully used for TRINITY.wad. For hackers only :-) I *do* hope you'll find DeuTex a bit easier to use, but Steve was a pioneer in the area of Texture editing! WACKER by Keith Wilkins A Graphic Texture editor. I could not test it, but it should be good. It would be a good idea to use it in combination with DeuTex. page 45 -------------- D) Known Problems -------------- - Color quantization is faster, but optimised for the Doom and Heretic palettes supplied with DeuTex. Else, it's slower and a bit lossy. - Identification of entry types does not always work with pwads made by programs other than DeuTex. There is no general solution to this problem, only my best effort. Sprites and Flats could be missed if certain conventions are not respected. Misidentified entries are stored as Lumps. - GIF format defaults to GIF87. - No MIDI support. MUS format is too complex to understand. No time. - DeuSF does NOT test that all REQUIRED sprite viewpoints are available if you change the number of viewpoints. Doom will lock up if you forget one of the sprite viewpoints. - If the -app command is interrupted, the pwad file becomes bigger due to appended waste data, but it is still operational. - DeuSF says stupid things if no command is given. - See TODO. *Limitations of Doom - Sprites in pwads only work if you don't reuse existing sprites. Use DeuSF or DMADDS if you want to replace sprites. Actually, DeuTex -merge will also work. (and better!) - Flats don't work in pwads. Use DeuSF or DMADDS if you want to replace Flats. Deutex -merge will also work. (and better!) *Limitations of Heretic - Sprites in pwad don't work at all. use -merge. I don't know why... page 46 ------ E) THANKS ------ First, thanks to you for taking the time to evaluate DeuTex/DeuSF. I know my program is not trivial to use, and might be tricky to understand, but I really think it's worth the trouble. DeuTex/DeuSF would not have existed without the help of these people: Steve McCrea Author of TRINITY.wad and DOOMTEX. Raphael Quinet Examples of GIF and DEU code. (quinet=montefiore+ulg+ac+be) Denis Moeller Author of NWT. Securisation and (denis=doomsday+sh+de) compatibility of DeuTex and NWT. Elias Papavassilopoulos Doom technical information. (ep104=cus+cam+ac+uk) Matt Fell Doom specs version 1.666 (matt+burnet=acebbs+com) Keith Wilkins Author of Wacker, first Texture (spike=nectech+demon+co+uk) composer. Try it! Tom Neff Doom technical information. (tneff) Bernd Kreimeier Author of DMADDS/DMADDF (bernd=nero+uni-bonn+de) Dewi Morgan Unashamed flattery that lead me to (D+Morgan=bradford+ac+uk) create DeuSF from DeuTex code. Id software For the DEUTEX/DeuSF test bench, also (help=idsoftware+com) known as 'Doom', 'Doom2' or 'Heretic' Raven software For those cool graphics in Heretic. (and for messing with color palettes) Special Thanx to: Mark Mathews DeuTex OS/2, DJGPP port. (mark+mathews=channel1+com) Improvements and suggestions. Per Allansson DeuTex Linux version. (c91peral=und+ida+liu+se) James Bonfield DeuTex DEC ALPHA port Chuck Rossi DeuTex SGIx port Sharon Bowles Detection of possible medusa effect Udo Munk DJGPP and Cygwin port page 47 -------------- THANKS (cont.) -------------- Thanks to all of you who reported bugs and proposed corrections or generally supported my efforts: Leonard Czajka leonardc=halcyon+halcyon+com Herve.Benvel Herve.Benvel=inria+fr Paolo Hutchison paolo=netcom+com M. Kernaghan mkernagh=julian+uwo+ca Thierry Vermat vermat=evol10+univ-lyon1+fr Jeremy Blackman ranma=eskimo+com Jason Mezzacca 72510+3424=compuserve+com C. Gasparo cgasparo=cymbal+aix+calpoly+edu Avery Andrews andaling=durras+anu+edu+au Matthew W. Miller mattm=infinet+com Kim Parrot kelm=eisa+net+au Martin {_|G|NRG} MartinG=munich+netsurf+de (I hope I'm not forgetting you!) Thanks to Justin Fisher for letting me use DeuTex and DeuSF on a new install for Alien-TC (despite all the small mistakes I made). Thanks to Jonathan Wilson for figuring out the formats of the Doom alpha and press release pre-beta pictures. Now comes the guy YOU all want to thank: HevKev, also known as Kevin McGrail, novice Manual Editor. 74107+1254=compuserve+com Before his contribution, I was the only one who knew how to use DeuTex. Now some of you might understand enough about DeuTex to use it in your great Doom conversions project. page 48 ----------- F) FINAL WORDS (AT LAST) ----------- Thanx for trying DeuTex. I did my best to make it the easy to use, bug free, and portable. However, it's not entirely trivial to use. I can't spend my life on a freeware tool. If you can't understand this tool, chances are your contribution to Doom fandom will be quite limited. Remember, I only worked to make your life as simple as it could be, so that even non-specialists could produce something cool for Doom. But don't forget that it takes some time, some dedication, and some genius also, to make something as great as Aliens-TC. Olivier Montanuy, E-Mail: Olivier+Montanuy=wanadoo+fr Address: Manoir de Keringant, St Quay Perros, 22700 Perros Guirec, FRANCE This is in Bretagne (Brittany), the westernmost part of France. Phone: +33 96482047 (time: UTC+1. Note this, Californian users!) modem: USR 14400 Worldport LITE Modem Fax.(this is not a BBS) page 49 APPENDIX I Switch Textures in DOOM.wad SW1BRCOM 128 128 * WALL62_1 0 0 * SW1S0 48 72 SW1BRN1 64 128 * WALL02_2 0 56 * WALL02_2 0 0 * SW3S0 16 75 SW1BRN2 64 128 * WALL02_2 0 56 * WALL02_2 0 0 * SW4S0 20 79 SW1BRNGN 64 128 * WALL62_2 0 0 * SW4S0 20 80 SW1BROWN 128 128 * WALL62_1 0 0 * SW3S1 48 72 SW1COMM 64 72 * W13_1 0 0 * SW1S0 15 18 SW1COMP 64 128 * COMP03_4 0 64 * COMP04_5 0 0 * COMP03_4 32 64 * SW2S0 16 72 SW1DIRT 64 128 * WALL00_7 32 0 * WALL00_6 16 0 * SW1S0 16 20 * WALL00_6 0 -16 * WALL00_7 48 0 SW1EXIT 32 72 * W32_4 0 0 * SW2S0 0 16 * W33_8 0 64 SW1GRAY 64 128 * W31_1 0 0 * W31_1 0 64 * SW2S0 16 70 SW1GRAY1 64 128 * W31_1 0 64 * W31_1 0 0 * SW4S0 19 79 SW1METAL 64 128 * WALL03_7 0 0 * WALL03_7 0 64 * SW4S0 20 68 SW1PIPE 128 128 * TP2_2 0 0 * SW3S0 48 76 page 50 SW1SLAD 64 128 * WLA128_1 0 0 * WARNB0 24 73 SW1STARG 128 128 * SW19_3 64 0 * SW19_4 0 0 * SW3S0 48 76 SW1STON1 64 128 * W28_8 0 64 * W28_8 0 0 * SW1S0 16 78 SW1STON2 64 128 * W28_5 0 0 * W28_8 0 64 * WARNB0 24 73 SW1STONE 64 128 * WALL01_1 0 0 * WALL01_2 16 0 * WALL01_3 32 0 * WALL01_4 48 0 * WALL01_1 0 72 * WALL01_2 16 72 * WALL01_3 32 72 * WALL01_4 48 72 * W33_8 0 64 * W33_8 0 120 * SW1S0 16 72 SW1STRTN 64 128 * SW12_4 0 0 * SW12_5 32 0 * SW1S0 16 72 SW2BRCOM 128 128 * WALL62_1 0 0 * SW1S1 48 72 SW2BRN1 64 128 * STEP07 32 72 * STEP07 0 72 * WALL02_2 0 56 * WALL02_2 0 0 * SW3S1 16 75 SW2BRN2 64 128 * WALL02_2 0 56 * WALL02_2 0 0 * SW4S1 20 79 SW2BRNGN 64 128 * WALL62_2 0 0 * SW4S1 20 80 SW2BROWN 128 128 * WALL62_1 0 0 * SW3S0 48 72 SW2COMM 64 72 * W13_1 0 0 * SW1S1 15 18 page 51 SW2COMP 64 128 * COMP03_4 0 64 * COMP04_5 0 0 * COMP03_4 32 64 * SW2S1 16 72 SW2DIRT 64 128 * WALL00_8 48 0 * WALL00_7 32 0 * WALL00_6 16 0 * WALL00_5 0 -1 * SW1S1 16 20 SW2EXIT 32 72 * W32_4 0 0 * SW2S1 0 16 * W33_8 0 64 SW2GRAY 64 128 * W31_1 0 0 * W31_1 0 64 * SW2S1 16 70 SW2GRAY1 64 128 * W31_1 0 64 * W31_1 0 0 * SW4S1 19 79 SW2METAL 64 128 * WALL03_7 0 0 * WALL03_7 0 64 * SW4S1 20 68 SW2PIPE 128 128 * TP2_2 0 0 * SW3S1 48 76 SW2SLAD 64 128 * WLA128_1 0 0 * WARNA0 24 73 SW2STARG 128 128 * SW19_3 64 0 * SW19_4 0 0 * SW3S1 48 76 SW2STON1 64 128 * W28_8 0 64 * W28_8 0 0 * SW1S1 16 78 SW2STON2 64 128 * W28_8 0 64 * WARNA0 24 73 * W28_5 0 0 SW2STONE 64 128 * WALL01_1 0 0 * WALL01_2 16 0 * WALL01_3 32 0 * WALL01_4 48 0 * WALL01_1 0 72 * WALL01_2 16 72 * WALL01_3 32 72 * WALL01_4 48 72 * W33_8 0 64 * W33_8 0 120 * SW1S1 16 72 page 52 SW2STRTN 64 128 * SW12_4 0 0 * SW12_5 32 0 * SW1S1 16 72 ; SW1BLUE 64 128 * COMP03_1 0 0 * COMP03_2 0 64 * SW2_7 14 66 SW1CMT 64 128 * WALL54_1 -42 0 * SW3S1 16 72 SW1GARG 64 128 * WALL47_2 0 0 * WALL42_6 12 62 SW1GSTON 64 128 * WALL48_2 0 0 * SW2_7 13 67 SW1HOT 64 128 * WALL49_1 0 0 * SW2_7 12 66 SW1LION 64 128 * WALL47_2 0 0 * WALL42_5 11 62 SW1SATYR 64 128 * WALL47_2 0 0 * WALL42_1 12 62 SW1SKIN 64 128 * HELL6_3 0 0 * SW2_5 0 59 SW1VINE 64 128 * WALL00_1 0 -16 * W106_1 0 0 * SW4S0 20 84 SW1WOOD 64 128 * WALL40_2 -64 0 * SW2_7 14 66 SW2BLUE 64 128 * COMP03_1 0 0 * COMP03_2 0 64 * SW2_8 14 66 SW2CMT 64 128 * WALL54_1 -42 0 * SW3S0 16 72 SW2GARG 64 128 * WALL47_2 0 0 * WALL47_5 12 62 SW2GSTON 64 128 * WALL48_2 0 0 * SW2_8 13 67 SW2HOT 64 128 * WALL49_1 0 0 * SW2_8 12 66 page 53 SW2LION 64 128 * WALL47_2 0 0 * WALL47_4 11 62 SW2SATYR 64 128 * WALL47_2 0 0 * WALL47_3 12 62 SW2SKIN 64 128 * HELL6_3 0 0 * SW2_6 0 59 SW2VINE 64 128 * WALL00_1 0 -16 * W106_1 0 0 * SW4S1 20 84 SW2WOOD 64 128 * WALL40_2 -64 0 * SW2_8 14 66 page 54 APPENDIX II Animated Wall Textures in DOOM.wad SLADRIP1 64 128 * WALL57_2 0 0 SLADRIP2 64 128 * WALL57_3 0 0 SLADRIP3 64 128 * WALL57_4 0 0 SLADWALL 64 128 * WLA128_1 0 0 ; BLODGR1 32 128 * TP5_1 0 0 BLODGR2 32 128 * TP5_2 0 0 BLODGR3 32 128 * TP5_3 0 0 BLODGR4 32 128 * TP5_4 0 0 ; BLODRIP1 32 128 * RP2_1 0 0 BLODRIP2 32 128 * RP2_2 0 0 BLODRIP3 32 128 * RP2_3 0 0 BLODRIP4 32 128 * RP2_4 0 0 ; FIREBLU1 128 128 * W65B_1 0 0 FIREBLU2 128 128 * W65B_2 0 0 ; FIRELAV2 128 128 * W73A_2 0 0 FIRELAV3 128 128 * W73B_1 0 0 FIRELAVA 128 128 * W73A_1 0 0 ; FIREMAG1 128 128 * W74A_1 0 0 FIREMAG2 128 128 * W74A_2 0 0 FIREMAG3 128 128 * W74B_1 0 0 ; FIREWALA 128 112 * WALL23_1 0 0 FIREWALB 128 112 * WALL23_2 0 0 FIREWALL 128 112 * WALL22_1 0 0 page 55 GSTFONT1 64 128 * WALL58_1 0 0 GSTFONT2 64 128 * WALL58_2 0 0 GSTFONT3 64 128 * WALL58_3 0 0 ; ROCKRED1 128 128 * WALL64_2 0 0 ROCKRED2 128 128 * W64B_1 0 0 ROCKRED3 128 128 * W64B_2 0 0 page 56 APPENDIX III Listing of sound names for Doom I and II *Ripped off from DMAUD by Bill Neisius* Then corrected and expanded to include Doom II sounds for this manual. DeuTex uses Doom's sound names rather than the artificial sound numbers used in DMAUD. A Conversion table for this follows. NOTE: An asterisk '*' means the sound is used for multiple functions. --------------------------------------- A) SOUNDS FOUND IN BOTH DOOM I and DOOM II --------------------------------------- Weapons DSPISTOL* Pistol firing DSSGCOCK* Shotgun cocking DSSHOTGN Shotgun firing (followed by cock) DSSAWUP Chainsaw start DSSAWIDL Chainsaw idle DSSAWFUL Chainsaw with trigger pulled DSSAWHIT Chainsaw hitting monster DSRLAUNC Rocket Launcher firing DSBAREXP* Rocket exploding DSFIRSHT Fireballs shot or passing DSFIRXPL* Fireball hitting object DSPUNCH Player punching DSPLASMA Plasma Gun firing DSFIRXPL* Plasma Round hitting object DSBFG BFG9000 firing DSRXPLOD BFG9000 round exploding Objects DSPSTART Floor/Lift starting DSPSTOP Floor/Lift stops (Clunk) DSSTNMOV Stairs/ceilings moving DSDOROPN Mechanical Door opening DSDORCLS Mechanical Door closing DSBDOPN Fast Door Open DSBDCLS Fast Door Close DSSWTCHN* Switch 'thunk' sound DSSWTCHX Switch 'pop' sound DSTELEPT Player/Monster teleport DSSLOP GUTS/SLOP (What the name says) DSITMBK Item Return in MultiPlayer DSBAREXP* Barrel explosion Player DSSKLDTH Player Push on wall DSNOWAY Player blocked by wall DSOOF Player hitting ground DSWPNUP Weapon pickup DSITEMUP Item pickup DSGETPOW Power up sound (Soul Sphere, etc.) DSPLPAIN Player injured DSPLDETH Player dying scream DSPDIEHI Player higher dying scream page 57 Former Humans DSPOSACT Former Human nearby breathing DSPOSIT1 Former Human sees Player DSPOSIT2 Former Human sees Player DSPOSIT3 Former Human sees Player DSPOPAIN* Former Human injured DSPODTH1 Former Human Death Moan DSPODTH2 Former Human Death Moan DSPODTH3 Former Human Death Yell Imps DSBGACT Imps nearby oinking DSBGSIT1 Imp sees Player DSBGSIT2 Imp sees Player DSCLAW* Imp clawing Player DSPOPAIN* Imp injured DSBGDTH1 Imp dying DSBGDTH2 Imp dying Demons/Spectres DSSGTSIT Demon/Spectre sees Player DSDMACT* Demon/Spectre nearby DSSGTATK Demon/Spectre chomping Player DSDMPAIN* Demon/Spectre injured DSSGTDTH Demon/Spectre dying Cacodemons DSCACSIT Cacodemon sees player DSDMACT* Cacodemon nearby DSDMPAIN* Cacodemon injured DSCACDTH Cacodemon dying Barons of Hell DSBRSSIT Baron sees Player DSDMACT* Baron nearby DSCLAW* Baron clawing Player DSDMPAIN* Baron injured DSBRSDTH Baron dying Lost Souls DSSKLATK Lost Soul attacking DSDMACT* Lost Soul nearby DSDMPAIN* Lost Soul injured DSFIRXPL* Lost Soul dying Spider Demon DSSPISIT Spider Demon sees Player DSMETAL Spider Demon walking DSSPIDTH Spider Demon dying page 58 Cyber Demon DSCYBSIT Cyber Demon sees Player DSHOOF Cyber Demon walking DSCYBDTH Cyber Demon dying Miscellaneous DSPISTOL* Menu selections DSPISTOL* Kills, Items, Secrets & Time at end of Level screen DSSWTCHN* Esc to main menu DSBAREXP* Level finished explosion at end of Level screen DSSGCOCK* Proceed to next Level at end of Level screen DSTINK "TINK" To Chat in Modem Play ---------------------------- B) SOUNDS FOUND ONLY in DOOM II ---------------------------- Weapons DSDBOPN Open Super Shotgun DSDBCLS Close Super Shotgun DSDBLOAD Reload Super Shotgun DSDSHTGN Fire Super Shotgun Revenant DSSKESIT Revenant sees Player DSSKEACT Revenant nearby DSSKEATK Revenant fires missile DSSKESWG Revenant swings at player DSSKEPCH Revenant punches player DSSKEDTH Revenant dying Mancubus DSMANSIT Mancubus sees Player DSMANATK Mancubus attacks DSMNPAIN Mancubus injured DSMANDTH Mancubus dying Pain Elemental DSPESIT Pain Elemental sees Player DSPEPAIN Pain Elemental injured DSPEDTH Pain Elemental dying Arachnotron DSBSPSIT Arachnotron sees Player DSBSPWLK Arachnotron walking DSBSPACT Arachnotron nearby DSBSPDTH Arachnotron dying page 59 Hell Knight DSKNTSIT Hell Knight sees Player DSDMACT* Hell Knight nearby DSCLAW* Hell Knight clawing Player DSDMPAIN* Hell Knight injured DSKNTDTH Hell Knight dying Arch-Vile DSVILSIT Arch Vile sees Player DSVILACT Arch Vile nearby DSVILATK Arch Vile attacks DSFLAMST Arch Vile shoots Flame? DSFLAME Arch Vile's Flame arrives DSVIPAIN Arch Vile injured DSVILDTH Arch Vile dying Final Boss DSBOSSIT Final Boss sees Player 'to win the game...' reversed DSBOSPIT Final Boss spits Cube DSBOSCUB Final Boss Cube lands and expands DSBOSPN Final Boss injured DSBOSDTH Final Boss dying Wolfenstein DSSSSIT Wolfenstein SS sees player. 'Schultstaffel'-'SS' DSSSDTH Wolfenstein SS dying. 'mein lieben' -'My Life!' DSKEENPN Commander Keen injured DSKEENDT Commander Keen dying Unknown DSRADIO Phone sound? Modem play? page 60 + ---------------------------------- + C) CONVERTING DMAUD sounds for DEUTEX + ---------------------------------- + + + + For all you DMAUD users out there, here's a chart you can use to + convert those DMAUD sound Numbers to Doom or DEUTEX sound names. + + + + DMAUD NO. DEUTEX/Doom Name + + + 1 DSPISTOL + 2 DSSHOTGN + 3 DSSGCOCK + 4 DSSAWUP + 5 DSSAWIDL + 6 DSSAWFUL + 7 DSSAWHIT + 8 DSRLAUNC + 9 DSRXPLOD + 10 DSFIRSHT + 11 DSFIRXPL + 12 DSPSTART + 13 DSPSTOP + 14 DSDOROPN + 15 DSDORCLS + 16 DSSTNMOV + 17 DSSWTCHN + 18 DSSWTCHX + 19 DSPLPAIN + 20 DSDMPAIN + 21 DSPOPAIN + 22 DSSLOP + 23 DSITEMUP + 24 DSWPNUP + 25 DSOOF + 26 DSTELEPT + 27 DSPOSIT1 + 28 DSPOSIT2 + 29 DSPOSIT3 + 30 DSBGSIT1 + 31 DSBGSIT2 + 32 DSSGTSIT + 33 DSBRSSIT + 34 DSSGTATK + 35 DSCLAW + 36 DSPLDETH + 37 DSPODTH1 + 38 DSPODTH2 + 39 DSPODTH3 page 61 + 40 DSBGDTH1 + 41 DSBGDTH2 + 42 DSSGTDTH + 43 DSBRSDTH + 44 DSPOSACT + 45 DSBGACT + 46 DSDMACT + 47 DSNOWAY + 48 DSBAREXP + 49 DSPUNCH + 50 DSPLASMA + 51 DSBFG + 52 DSCACSIT + 53 DSCYBSIT + 54 DSSPISIT + 55 DSSKLATK + 56 DSCACDTH + 57 DSSKLDTH + 58 DSCYBDTH + 59 DSSPIDTH + 60 DSHOOF + 61 DSMETAL page 62 APPENDIX IV DeuTex and DeuSF COMMAND SUMMARIES --------------- A) DeuTex COMMANDS --------------- Command Line Format: DEUTEX <-optional cmds.> <-other cmds.> ******** 1) STAND ALONE COMMANDS: -dmtextures Lists the Doom Textures in TEXTURE?.TXT. -check Will look for Textures containing void columns. -help Lists the parameters. -syntax Prints short listing of the format of wadINFO.TXT. -unused Checks for unused bytes in a pwad. ******** 2) OPTIONAL COMMANDS: -doom Defines the Doom or Doom2 directory. -dir Defines the working directory. -deu* Add 64K at the end of your pwad for DEU. -rgb Defines the color used for 'transparent'. -bmp \_________________/ Format used when EXTRACTING pictures. DeuTex -gif / \ recognizes both when STORING pictures. -ppm / -wave \_______________/ Format used when EXTRACTING sounds. DeuTex -au / \ recognizes both when INSERTING sounds). -voc / -fullsnd* For extracting oversize sound entries. -level \ / These tell DeuTex to select sprites, patches, -lump \ / sounds, etc. when composing, decomposing, or -texture \___________/ merging pwads. Commands can be combined. -sound / \ By default, all entries are selected. -graphic / \ Those switches can be combined. -sprite / -patch / -flat / -o tells deutex it can overwrite the data file if they exist -s_end tells deutex to use S_END not SS_END for sprite pwads (note: if you're not a hacker, this is useless to you.) ******** 3) OTHER COMMANDS: -iwad Used with -make, makes iwad instead of a pwad. -wadir Directory list, with entry identification. -get Get a single entry from a wad -extract Extracts resources from a pwad and puts them into a subdirectory having the resource name. -usedtex List the textures used in a wad. -make Reads wadINFO.TXT and uses it to compose MYOWN.wad from the files in the subdirectories. -merge Will merge MYOWN.wad with DOOM.wad. -restore Will restore DOOM.wad and the merged MYOWN.wad. -join Will merge THIS.wad with MYOWN.wad -app Will append Doom sprites to MYOWN.wad -res Will restore MYOWN.wad All these commands are like those of DeuSF -as Appends all sprites. Short for -sprites -app -af Appends all flats. Short for -flats -app page 63 -------------- B) DeuSF COMMANDS -------------- Command Line Format: DeuSF ******** 1) STAND ALONE COMMANDS: -help Lists these parameters. -format Displays format conventions a pwad must follow. -wadir Lists the entries in the pwad directory. ******** 2) OPTIONAL COMMANDS: -doom Defines the Doom or Doom2 directory. -sprite Used with -add or -app, to add only sprites or only Flats. If -flat neither of these commands is present, DeuSF will add both. ******** 3) MANDATORY COMMANDS: these are the same as the equivalent DeuTex commands. DeuSF is only a small version of DeuTex, meant to install sprites and Flats pwad on the disk of the end user. -merge Will merge MYOWN.wad with DOOM.wad. -restore Will restore DOOM.wad and the merged MYOWN.wad. -join Will merge THIS.wad with MYOWN.wad -app Will append Doom sprites to MYOWN.wad -res Will restore MYOWN.wad All these commands are like those of DeuSF -as Appends all sprites. Short for -sprites -app -af Appends all flats. Short for -flats -app Page 64