Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Linguica

Importing tall sprites to work in vanilla

Recommended Posts

Hi, I am curious if there are any modern tools to import a sprite taller than 128 pixels and have it work correctly in vanilla.

Say I wanted to make a new weapon HUD sprite that completely covers the screen. So I import a 320x200 image into a WAD, set it as a weapon sprite, etc. If you do this in SLADE, the result in vanilla will be that the image will be drawn wrong. The issue, as I understand it, is that while a post can be up to 256 pixels high, the vanilla Doom engine will only display 128 pixels' worth of a graphic entry before starting to repeat from the beginning.



The obvious solution is to break up the image into 2 posts. This can be trivially done by placing a transparent row at 128 pixels down from the top, and then when it's imported, each column gets broken up into 2 posts, and the whole thing will draw properly:



Of course, then you have the problem of one transparent line in the image. So I exported the graphic as a raw lump, opened up a god damn hex editor to find the spots where the offset of the second post in each column start, and manually change them all to be one higher.



So after doing this, it worked perfectly:



ANYWAYS so this is clearly a sub optimal workflow. I'm curious if any modern utilities support breaking up long posts into multiple posts so vanilla Doom will display them correctly. SLADE and XWE both seem not to be able to do it. Deepsea might be able to, but I really don't want to descend into F7 hell. I'm pretty sure if I went back to Wintex or Deutex, they do it automatically, but I'd prefer to use something that actually runs on modern Windows.

Share this post


Link to post
Linguica said:

The obvious solution is to break up the image into 2 posts. This can be trivially done by placing a transparent row at 128 pixels down from the top, and then when it's imported, each column gets broken up into 2 posts, and the whole thing will draw properly:

Just to clarify, how exactly did you put two posts in a single image? Is this demarcated by the transparent pixels, or something else in the image or lump? I read through both your post and the wiki article, but it still seems a bit vague.

Share this post


Link to post
BlueFeena said:

Just to clarify, how exactly did you put two posts in a single image? Is this demarcated by the transparent pixels, or something else in the image or lump? I read through both your post and the wiki article, but it still seems a bit vague.

The Doom image format, internally, stores for each column a list of every run of non-transparent pixels in that column. So starting from the top of any column, you go down until you hit a non-transparent pixel. That's the start of post 1, and it continues as long as there are pixels. Then if you hit a transparent space you stop that post, and then keep going until you hit another non-transparent pixel, and you start writing post 2, etc.

Because of the way the engine was coded, you can only properly draw a post 128 pixels high, so if you want an image taller than that, you need to store it in several consecutive posts.

Share this post


Link to post

Yes, that's quite a problem. SLADE 3 (probably XWE too) supports DeePsea's tall patches, which are used by several ports but not compatible with vanilla. So the alternative method you suggest is not supported by any editing tool as far as I know.

Share this post


Link to post

Uh... there ARE historical vanilla WADs that got around this, right? My initial thought was it must have been supported in DeuTex from the beginning, because I remembered ALIENS-TC, with the big power-loader weapon sprite, so I went to go look at it in Chocolate Doom:



Seems normal, right? It wasn't until I compared it to the graphic directly that I noticed:



The sprite DOES wrap after 128 pixels! It's quite clear on the left side, and on the right side you can see something kind of amazing: the author not only vertically aligned the tube running down the side, he also put a little one-pixel notch in the tube near the top so that the new posts in those columns would all line up together! That was some excellent artistry on Justin Fisher's part to make that so non-obvious.

Share this post


Link to post

But... other vanilla WADs had big sprites, right? I remember allhell.wad had a super-Cyberdemon, that must have been bigger than 128 tall.



...oh, it wrapped after all. You can see the top of the head intruding on the leg there.

OK, uh, Batman Doom had some big-ass sprites, right?

Like this helicopter sprite, it's hard to tell, but there's a column that is TOTALLY taller:



Here it is, sort of boxed in:



It's hard to tell, but that column is something like 140 continuous pixels long. So there, Batman Doom had sprite posts longer than 128 pixels, it's settled.







...







......









except... hrm...










OH MY GOD

Share this post


Link to post

It's pretty amazing how much arcane knowledge is casually stuck in these early wads... with no documentation like it's no big deal.

Share this post


Link to post

Posts are confusing with that extra byte in them. Does anyone know why id did it that way? I know they expanded the header sizing vars at least twice when going from Alpha to Beta to the final format, but they left that extra byte at the end.

(Not really related, unless it pisses you off while hex-editing posts :)

Share this post


Link to post

Holy shit guys.

Linguica said:

Hi, I am curious if there are any modern tools to import a sprite taller than 128 pixels and have it work correctly in vanilla.

Say I wanted to make a new weapon HUD sprite that completely covers the screen. So I import a 320x200 image into a WAD, set it as a weapon sprite, etc. If you do this in SLADE, the result in vanilla will be that the image will be drawn wrong. The issue, as I understand it, is that while a post can be up to 256 pixels high, the vanilla Doom engine will only display 128 pixels' worth of a graphic entry before starting to repeat from the beginning.

http://i.imgur.com/D3ui7XG.gif

The obvious solution is to break up the image into 2 posts. This can be trivially done by placing a transparent row at 128 pixels down from the top, and then when it's imported, each column gets broken up into 2 posts, and the whole thing will draw properly:


First thing first: my doom2.wad is unmodified.

Compare with the values there.

Now let's take a look at the raw values in TITLEPIC.

Let's see the first column...


Holy shit. It's split. That column is split in a 128-long post at offset 0 and a 72-long post at offset 128. And then the next column, same thing: 0 128 + 128 72. And the next. And all of them.

Which means that if you just copy the TITLEPIC and rename it as a weapon sprite, then it'll work in vanilla. You have to reconvert it to see it glitch like in Linguica's gif.

But yeah. All this time, all this time, the split-at-128 trick for tall pictures had been used, under our nose, it was literally the first thing we saw when Doom finished loading, and we never knew. People went and invented weird tricks like the DeePsea tall patch format when there was a simpler, and official solution all along. (Disclaimer: weird trick still needed for images taller than 256 pixels.)

One thing about the 128-limit is that it results in larger files. TITLEPIC is 66888 bytes when written with a single post per column, but 68168 bytes with the 128 split -- an about 2% size increase. Alright I don't think anyone will really mind, so no need for an option.

Anyway, this monster bump is there to say that it's there. You may now rejoice that it only took like two years for like six lines of extremely simple code.

Share this post


Link to post
Gez said:

Anyway, this monster bump is there to say that it's there. You may now rejoice that it only took like two years for like six lines of extremely simple code.

Thank you. I was just going to suggest this as a feature for SLADE as this issue came up a few time with the sprite fixes. This addition will simplify handling that matter in the future.

Share this post


Link to post

Ha, yeah I remember that! And the Evilution guys inadvertently screwed that frame up in their iwad because they used some unofficial tool or something.

Share this post


Link to post
Linguica said:

I am glad to see it finally has been implemented! I should mention though that Da Werecat pointed out that id used this trick on the shotgun reloading sprite way back in 2015: https://www.doomworld.com/vb/post/1531983

VGA said:

Ha, yeah I remember that! And the Evilution guys inadvertently screwed that frame up in their iwad because they used some unofficial tool or something.

Nice find.
Yes, many of the TNT IWAD graphics have different checksums than their Doom counterparts. Strangely, as VGA mentions, this appears to be the case on many sprites that did not need to be reprocessed. Maybe they ran CLEANWAD on it, which attempts to shave bytes off of many different resources.

Example:
BAR1A0 - Doom2: 944 bytes
BAR1A0 - TNT: 943 bytes

Share this post


Link to post

I suspect they just used DEUTEX to export all IWAD resources (converting them to "external" formats like BMP and WAV in the process) and then rebuild it with their additional/replaced TNT resources.

Another consequences is that the sounds that are 22 kHz in Doom II are 11 kHz in TNT.

Share this post


Link to post

interestingly the code for all of this has been present in lumpy (present in the doom utilities package) all this time. The "PATCH255" grabber explicitly splits at 128 because as they mention in the comment, the texture mapper does wrap. Since they seemed to use the same grabber for sprites and wall patches, all patches are offset as if they were sprites. I'm not sure what they used to create screen graphics though, since all of them don't have offsets.

The comment on the patch generation from the file is kinda interesting overall. From the grabcmds.c file at line 616:

// grab a segment
// an extra pixel is grabbed at the start and end of the column
// to keep a round off error from grabbing a strange pixel

// don't grab more than 128 high, because the texture mapper wraps
// fake it with two contiguous columns
The second bit refers to the wrapping thing, but the first bit is interesting. I'm curious what kind of round off error was being encountered...

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×