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

Have you ever run Doom below system requirements?

Recommended Posts

Mode Y is simply mode X at, as you said, 320x200 resolution. It mantains all the advantages and disadvantages of a planar mode, so again, it would be deleterious to use it for something like Doom.

For something like Jazz Jackrabbit though, with its scrolling backgrounds, gradient fills, and sprite-based operations (without scaling), it would be perfect.

Same thing for many oldschool demoscene effects: you can speed up filling a (flat) shaded 3D polygon by a factor of 4x or achieve plasma cube/BOB effects easily if you use Mode X/Mode Y, but when it comes to pixel-precise rendering such as the one required by Doom, it would just slow things down.

Doom simply used VGA Mode 13h with double buffering. This article explains how it's done. It's a pity that VGA had a so dumb programming mode that it was not possible to do it within VRAM entirely without using Mode X, so one of the two "buffers" was actually within system-memory. So at every frame there was a potentially costly main RAM-to-VRAM transfer.

This may also explain why some game might have been faster: on some systems it might have been faster to let the VGA do this transfer via DMA once per frame, in a single block On others, it might have been faster to use direct OUT commands to a specific port, and some VGAs may plain and square suck at copying from main RAM.

Share this post


Link to post

You are right that mode-X or mode-Y is not a good choice for a game like doom. Pixels are not stacked together, for example 1st, 5th, 9th and so on pixels reside in the first of the four planes and I think at near bytes. Of course one wouldn't have to switch planes for every pixel, just copy from an offscreen buffer (in system memory) each byte of 1st, 5th, 9th, etc pixel to the videoram, then switch to the second plane and do the same for pixels 2,6,10,etc and copy to the appropriate bytes in vram, then all pixels of plane 3 and then 4. But then this would be strange, what is the point of having page flipping if you still have to copy to the non-visible videoram (I think it doesn't matter if visible or not, you still take the same penalty for writting to video memory) and even doing it one byte at a time which is even more slower?

About whether doom uses a mode-X alike mode or not however, as long as I search on the internet I still find references that doom in DOS was doing this. Of course people could be misinformed, though I have also found another source from the programmer himself Wolf3d dev. "Wolfenstein (and Doom) originally drew the characters as sparse stretched columns of solid pixels (vertical instead of horizontal for efficiency in interleaved planar mode-X VGA)"

Looking at the source code of Wolfenstein3d and Doom, for the first one it's clear that it switched to un-chained mode. However, I couldn't find any evidence of this in the released doom source code for Linux. Some X11 commands open the display and switch to a video mode that could be pure 13h and use an offscreen buffer in system memory to copy directly to the videoram (I guess 32bit copies this time). It's quite possible that the Linux version or the released source code didn't use the Mode-Y mode as the original game in DOS might do. And since we don't have the original DOS code, it's hard to tell.

Share this post


Link to post

Ummm.... DOOM definitely used Mode-X, not in the first versions but later on it did, its obvious due to the fact that page-flipping was in fact used, not double buffering (at least in the traditional sense) and the existed a file called PLANAR.ASM in the original DOOM sources, which rendered to screen planar, as well as V_DrawPatchDirect, which shows obviously a planar screen mode is used, i.e. Mode X

Share this post


Link to post
shadow1013 said:

Ummm.... DOOM definitely used Mode-X, not in the first versions but later on it did, its obvious due to the fact that page-flipping was in fact used, not double buffering (at least in the traditional sense) and the existed a file called PLANAR.ASM in the original DOOM sources, which rendered to screen planar, as well as V_DrawPatchDirect, which shows obviously a planar screen mode is used, i.e. Mode X


Interesting. At which version of Doom did they changed to Mode-X?

It is still strange to me that they made this change because of the reasons we discussed above (the slow 8bit copy, because mode-X configuration makes you do it), it's definitelly a drag in a PC with a good CPU (a Pentium 1 even) with slow ISA gfx card, but maybe a little gain there is in a slow 486SX with very fast VLB card. Most people told me it will be a speed upgrade because you select the screen page to be shown yet it will apear when the next vblank comes, so you can start rendering the next frame already in between (in a third non-visible page), also no memcopy from system memory buffer too, so there is some time gained but I see it mostly as a drag.

I should try some tests with various versions of Doom in a good CPU with slow videocard machine. I was curious about this several years ago.

p.s. Another thing that bugged me with the old Doom engine is when I realized it's actually locked at 35fps and not 70fps which was the standard refresh for the VGA mode used. Of course it could be a design choice, they might have wished to avoid jumping frame rates from 35 and above, so they locked it into something that seemed ok. An optional choice to have it unlocked to 70fps for people with Pentium or more would be nice, but I guess the gameplay ticks where programmed for 35fps and it would be hard to change at the time. Modern ports interpolate the enemies and player positions I guess. I got used while playing Zdoom and have a hard time getting used to the original 35fps.

Share this post


Link to post

Well, the drawing functions themselves operate on a perfectly chunky (linear) buffer. I can't think of a good reason to use Mode X (or Y) on DOS other than avoiding doing in-memory double-buffering, but then they would have to do chunky-to-planar munging at every frame, which would take away some considerable amount of CPU time.

For Wolf3D it would make sense because of the solid-filled floors and per-column optimized renderers, but not for Doom. Seems like a very unclear tradeoff to me. Can anyone check out with an IDA if there's indeed a constant chuncky->planar munging going on?

Obviously, most source ports DON'T do anything of the sorts.

As for the ticrate thing....it has been amply covered in other threads. I once even tried to make a branch of Mocha Doom with a halved ticrate (so that the ENGINE itself runs at 70 fps, not just the display, and not just an interpolation) and it was eerily smooth, but it was tricky to guess what to scale and what not (e.g. monster speeds per-tic needed to be halved, but movement-checking code was not as simple to "upgrade"). The VGA card, in any case, still refreshes the raster at 70 Hz, at that resolution, regardless of what you are doing with the VRAM, so that 70 Hz figure would stil be an upper limit ;-)

Share this post


Link to post

Well, remember DOOM draws nearly everything in columns, which is easy to draw in Mode-X, all patches screens and textures are column-major. so yeah, its about the same thing, the only difference being *I think* flats. The change probably occurred sometimes after 1.2, as heretic and hexen are both simple mode 13h. Yet, as a curiosity they still have some references to Mode-X in their code

Share this post


Link to post

Still, if you check out how chunky screen columns would end up being arranged in the planar Mode X, you'll see that this couldn't have possibly benefitted Doom in any way, because two sequential pixels in the same plane actually corresponded to two pixels 4 positions apart in chunky mode, and two pixels over-under in chunky end up being totally apart in planar mode (e.g. column 0 would contain pixels x,y: (0,0), (0,1), (0,2)... with linear addresses of (320*0+0), (320*1+1), (320*2 etc) which would all end up being on the same plane 0 but distanced, according to the Mode X layout, so none of the multiple-plane plotting tricks would work: these only work for pixels within 4 horizontal places of each other (pixels with the same plane linear address, but on different planes).

It's not like ModeX could be used as a faster screen transposition mechanism, and it wouldn't even be needed, as column functions were hardwired to plot stuff vertically, anyway. All that was needed was to transfer a chunky buffer to the screen ASAP.

The only aspects of Mode X that could be -marginally- useful to Doom would be faster screen clearing in the automap (writing only 1/4th of the black pixels necessary, by using the cheap trick of setting all 4 planes to receive the write), and perhaps accelerating low-detail mode by writing a pixel on two or more planes planes at the same time (e.g. by writing a pixel to plane 0 and plane 1 at the same time, two continuous horizontal pixels are written with just one OUTP command, so this could offer a truly accelerated horizontal detail halving (or ever thirding and quartering mode). But I wouldn't bet on the fact that Doom actually did that, but maybe the WATCOM C code remnant in the low-detail functions could shed some light over that.

Edit: in R_DrawTranslatedColumn of the original SC there's this bit of commented out code:

// WATCOM VGA specific.
    /* Keep for fixing.
    if (detailshift)
    {
	if (dc_x & 1)
	    outp (SC_INDEX+1,12); 
	else
	    outp (SC_INDEX+1,3);
	
	dest = destview + dc_yl*80 + (dc_x>>1); 
    }
    else
    {
	outp (SC_INDEX+1,1<<(dc_x&3)); 

	dest = destview + dc_yl*80 + (dc_x>>2); 
    }*/
Those writes to SC_INDEX are similar to the examples on the page I linked to before, and seem to select planes 3&4 (first occurence, (SC_INDEX+1,12), 12= 0xC = 1100) and 1&2 (second occurence, (SC_INDEX+1,3), 3 = 0011) which write a single pixel to multiple VGA Mode Y planes, otherwise only a single pixel on a specific plane is selected (outp (SC_INDEX+1,1<<(dc_x&3))).

Therefore, this at least confirms that Mode Y was at sometime considered.

The problem is that these remnants are present only in R_DrawTranslatedColumn and R_DrawFuzzColumn (a similar one), and as you may have noticed Doom actually has dedicated functions that draw low-detailed columns directly without checking for the detailshift condition when INSIDE a drawing column, at least in the SC release. Only a full decompilation of Doom.exe would provide definitive evidence of what was actually used where.

Share this post


Link to post

*shrug* even assuming that they did really use Mode Y for everything, it makes little sense: for full-detail screen writes (and for menu draws as well) using it would bring no advantage, quite the opposite: every actual pixel write would have to be preceded by a plane selection command unless they optimized the column functions to write all pixels of one particular plane together, a-la Wolf3D, and then moving on to the next planes.

This could only be justified in low detail mode which actually DID write multiple pixels with one command, but not in full-detail, where even if you did the best possible Mode Y column drawing function, it would still not be able to beat a "chunky" one, clock-per-clock.

Also, using Mode Y doesn't seem to make column-based calculations any easier: they still have to do the same coord mumbo-jumbo for every pixel. It really makes one wonder why it was considered (or even worse, chosen) at all. If it turns out they REALLY adopted it, then it might explain why some VGAs fare so much worse than others: not all had fast register manipulation (the most easy way to check that is to use a game that does a lot of palette manipulation: some VGA cards just choked on those).

Share this post


Link to post

well they had to do a outp every column, don't forget that DOOM picture format is column major, it actually seems quite similar to the wolf3d sprite format in retrospect (although obviously not exactly), but your right, it does make little sense

Share this post


Link to post
shadow1013 said:

well they had to do a outp every column, don't forget that DOOM picture format is column major, it actually seems quite similar to the wolf3d sprite format in retrospect (although obviously not exactly), but your right, it does make little sense


That doesn't help at all, because Mode X and Y aren't column major they are simply "column-sparse": to write e.g. to column 1 (out of [0-319) you have to direct your writes to pixels 1, 321, 641 etc. in sequence.

These pixels all happen to belong to Plane 1 (because it contains all pixels [1,5,9, 13, etc.] and in general all pixels with a formula of 1+4n. To write however to particular column x at a height of y, you still need to use a formula such as this one:

VGA[(y<<6) + (y<<4) + (x>>2)]=color
There's no fast&easy conversion of column-major to row-major, as you seem to imply, and no way to take shortcuts.

Writing to a different plane and/or to multiple planes would just help with doubling/tripling/quadrupling columns, which is only useful for fast color fills, screen clearing and Doom's low detail mode. For single pixel-by-pixel writes, it offers no advantage, and surely no automagical column-major-to-row-major conversion. Let alone that any such function would only benefit fix-scale graphics, not sprite-drawing functions that use scaling/skipping/stepping of data.

A better way to think of Mode X/Mode Y is that you split your normal screen into 4 screens, each of which contains just the (4n), (4n+1), (4n+2) and (4n+3) columns of your chunky screen, and thus each one only has 1/4th of the pixels. However addressing within each of those screens remains exactly the same as normal chunky display (in this sense, it's not even a proper planar display, as you still write a full 8-bit color each time). Where's the supposed column-major acceleration in that, unless you're doubling/tripling/quadrupling your screen writes for lower detail?

Edit: the only special VGA mode that would help Doom accelerate its column-major mode would be "Mode Q": a planar 256x256 mode which allowed screen writes to be performed simply by placing the x and y coords in a single short word, as simply as swapping them. This would indeed allow trivial conversion of columns to rows (and viceversa) and the column functions could be modified to render the screen "sideways", thus simplifying pixel-writing iterators a lot. But this only holds for perfectly square screen modes (and in general, for square matrixes whose rank is a power-of-two). Perhaps that's what you had in mind?

Share this post


Link to post

a 66mhz 486 with 8 megs of ram is the slowest thing I ever played Doom on.

In Doom II the game ran good, but every once in a while you could feel it just barely slowing down, like maybe 30 instead of 35 at some points.

Ran in high detail mode and no screen size reduction (beyond it showing the status bar, mind you).

As for shitty performance with Doom, I remember running Doom 95 on a similar system and it ran god awful.

Share this post


Link to post

Doom draws to a linear buffer in memory. No modeX or whatever voodoo.
For this reason 'DrawPatchDirect', or whatever it's called just calls 'DrawPatch' and draws into screen0(a linear memory bitmap).
The final memory->backscreen move was done onto an x'd mode. And that x mode was also used to switch between view/back screen.

Share this post


Link to post

Then what's the point of jumping through all those hoops? -_-

If they didn't exploit fast screen blanking or even the "output one pixel, write two/three/four" low-detail trickery allowed by Mode X/Y, then the only valid reason for using it is to be able to use the Mode X/Y page flipping mode. Great, that saves like, 64 KB of RAM at the cost of ass-backward single-pixel writing operations, and is not even guaranteed to be faster on all VGAs.

Sounds more like the leftover of a premature optimization which was later on too hard to completely eliminate from the codebase. Everything would've been much simpler and probably faster if they simply used chunky VGA and did a linear memory->VGA memcpy.

Wolf3D, with its flat floors, coarse columns and in-place dynamically-compiled column "shaders", was a different beast altogether.

Share this post


Link to post

Early Doom alphas featured an interleaved column-major image format which would have made sense in a planar mode; but it was used for full-screen pictures and HUD elements rather than the game world render.

The renderer used column-major format for sprites and patches because these elements are rendered by columns; while flats are row-major because they're rendered by rows. It composes an images from these two passes in a buffer and then send that to VGA.

So either the image is composed in planar format and sent in planar format; or it's composed in chunky format and sent in chunky format. Swapping bytes around to convert between both for every frame would be a huge and pointless waste of time.

Share this post


Link to post
Gez said:

So either the image is composed in planar format and sent in planar format; or it's composed in chunky format and sent in chunky format. Swapping bytes around to convert between both for every frame would be a huge and pointless waste of time.


With a carefully optimized converter/iterator, it can be done with reasonable efficiency (Essentially, use 4 base pointers for 4n, 4n+1, 4n+2 and 4n+3 pixels and increment them by 4 bytes, doing sequential writes into plane 0,1,2, and 3, 16000 pixels each), but it would still be no match for an optimized memcpy, at least on Intel.

There's no deny that the drawing functions all operate in chunky (linear) format, at least those appearing in the Linux source code release. But the DOS one is a real sphinx, and it could very well be that they are actually using planar at some point. However, the fact that you can only find error messages for e.g. R_DrawColumn and NOT R_DrawColumnLow should ring a bell: they must be using a dual-purpose functions, which could very well be using that cheap Mode X/Y column doubling trick.

That weird mode in the alphas might also be a failed attempt at switching to a HiColor mode for all we know (writing 16-bit "pixels" but without actually switching video modes. A screenshot and byte-by-byte analysis to see what was actually written, e.g. recognizable RGB555 values, might help shed some light on that but I'm digressing).

Share this post


Link to post

I had a 33hz "486" (my first PC) and it didn't run Doom in "maximum settings", so I had to shrink the screen-size a bit, and perhaps even lower the pixel-count quality with the F5 button

amusing memories :)

Share this post


Link to post
GoatLord said:

I suddenly remember playing "Rise of the Triad" at an electronics store around '94 or '95. I got motion sickness and actually had a goddamned seizure and fell the fuck over. My dad said my face was white and my lips were blue. Only time that's ever happened! But hey, I was like 10 or something. Maybe I was too young to handle psuedo-3D games. 'Cept I had already played "Doom" and "Wolfenstein 3D" by that point so I dunno.


Shrooms mode: Not even once.

Share this post


Link to post

After checking out the "only two ASM functions present in Doom", according to Carmack himself (check README.asm in the linuxdoom sc), it's clear that they simply do chunky writes. There's no funky ModeX stuff being done there, not even to achieve a cheap "get two pixels at the price of one!" trickery. If those functions ever used Mode X/Mode Y at some point, that sure didn't survive all the way unto v1.9, and the SC release only shows enigmatic remnants.

If Doom does indeed use Mode X/Mode Y for the page flipping, it must be occuring a chunky-to-planar conversion penalty somewhere down the line (and more specifically, in one of those system-specific I_ functions that finalize the screen output and flip the pages).

Now, if someone could provide a disassembly of the right spot in the code (by e.g. identifying accesses to the VGA registers or a switch to Mode X), that would close the question once and for all.

Still...that really makes me wonder if Doom was really as fast as it could be. Sometimes I think it's a miracle it was even acceptable on a 486, and that it could beat all FPS that came after it in performance.

Share this post


Link to post

Thats a little harsh. Perhaps the inner loops and lower level utilities of the software renderer aren't as tight as they could be. However this is irrelevant when one considers the efficiency of the design employed at the high level.

It surprises me how often developers painstakingly micro-optimize when cleverer high level thinking can result in optimizations magnitudes more effective.

Share this post


Link to post

I have just finished reading the interesting comments since last time. Many suggestions here. Bruce says chunky rendering was done and then converted to planar to have page flipping. Gez says it should be either planar to planar or chunky to chunky but not rendering to chunky and converting to planar since that would be senseless. Still, I am mostly convinced the first suggestion is what really was done, chunky rendering in a buffer but then converting from chunky to planar. Not very optimal I know :P

My initial worry was still the slow 8bit blitting necessary with the chunky to planar. However, it would be possible to do the planar to planar thing suggested. Since as the sprite and wall drawing is done vertical in columns, only once per column for each wall or sprite a memory position calculation (something like the pointer = (y<<6) + (y<<4) + (x>>2))would be needed, but this time only to find where to write in a system memory buffer using the same configuration we would found on a Mode-X/Y mode. Then, a simple increment pointer+=80 would move vertically in the buffer. We would possibly have four 16000 byte buffers in system memory for four planes. So after finishing rendering planar style in the buffers, planar to planar vram 32bit blit would be easy. So, it's not impossible and no shift conversions per pixel but only per column. However, my tests say this method was not used.

But if as it's said the first versions of Doom (and Heretic/Hexen) were written in pure 13h the rendering routines would follow the chunky logic. If at a later point for some reason they decided to use Mode-X because they thought there could be a gain in PCs with fast CPUs and video cards, the only brute force option would be preferable to just make the conversion with the slow one byte at a time copying from chunky to planar vram, because converting all the wall and sprite column rendering to use the above solution could take too much time, I even forgot that the floors are rendered horizontally (rendering could be converted to a vertical fashion for them too if everything was planned initially to fit ModeX).

Someone mentioned Heretic doing the old 13h. Also doom early version but I have later versions and didn't bother to downgrade which I might try tonight. The only test I could do yesterday was to try timedemos in my Asus EEE pc booting DOS from a USB. Fast enough CPU for doom and heretic, so CPU isn't a bottleneck and only the video bandwidth remained. Some VGA benchmark tests I did showed the maximum 32bit blit at 320*200*8bpp (13h mode) is around 200fps. I run several timedemos I captured with Doom and Heretic and calculated (gametics / realtics) * 35 (I hope it's the same formula for Heretic too, though from the speed I think it's also a 35er game). Anyway, doom wasn't doing over 50-60fps. Heretic did very close to the therotical 200 always. This is one first evidence for me about the 8bit ModeY vs 32bit blit in regular 13h difference. If I manage to downgrade Doom today and see such big differences with similar timedemos I am convinced something stinks.

p.s. And if it's true I'll keep the downgraded doom version for my 386/486 computers. The 386 is bound by the CPU so I might not see any difference but a 486 with a not so fast gfx card could show improvement (although I have inserted the fastest VLB I could find from all my gfx cards I have benchmarked :)

Share this post


Link to post

The "proof" that modeX is used is evident when quitting Doom under Dos or dosbox... vertical stripes appear before delving back to the beautiful DOS prompt... even when using Doom v1.9.
Isn't the original DOS source available somewhere? I think knocking on Romero's ballsack to release some info on the subject would be the best solution... or maybe Abrash for he was the one flirting with Carmack online during 92/93 and as its inventor known to be a ModeX proponent.

Share this post


Link to post

i played doom on a 386 and it ran smoothly only when i scaled down the window. it was on a 14" monitor, so i had a perhaps 10" game view.

doom2 ran so badly on it that i had to upgrade. the first maps were ok, but map 6 slowed to a crawl in the spider room and map 7 went like fireballs / freeze / dead.

the 486 solved that problem, i went on keyboarding happily with pc speaker sounds until i visited a guy who had a sound blaster. eh, wait, what's that? i couldn't believe what i missed.

interestingly, i had no problem seeing all the game's details in 320x200 back then... heh, i guess we're so jaded by now.

Share this post


Link to post
_bruce_ said:

Isn't the original DOS source available somewhere?


You do realize that this is pretty much the Holy Grail of Doom source ports and related modding, right?

If I didn't suck at using IDA I could come up with an answer pretty quickly, but so far we only have fragmentary facts and circumstantial evidence. Just trying to piece everything together here:

  • A game like Doom would make 100% sense in chunky mode, while planar would be, at least on paper, totally unsuitable...
  • ...however in order to have in-place double-buffering with VGA you needed to use Mode X or Y or any of the more obscure unchained modes...
  • ...but you could also achieve it with main RAM-to-VGA mempcy's at the end of a page flip.
  • There are some remnants of code (R_DrawTranslatedColumn, R_DrawFuzzyColumn, the "WATCOM VGA SPECIFIC" stuff) that clearly wrote pixels in Mode X, even using the multi-pixel output trickery to speed up low-detail...
  • ...but this doesn't match the .asm code for R_DrawColumn and R_DrawSpan found in the Linux SC release, which tells a different story, and is clearly chunky. So which one was it?
  • Using Mode X or any non-chunky mode if the drawing functions were actually chunky would imply that a chunky-to-planar conversion has to take place at the end of every frame. Whether the double buffering could offset that under any circumstances is dubious at best.
...it just boggles the mind, doesn't it? ;-)

Share this post


Link to post

Doomworld: Ask a yes or no question, and you get an in-depth discussion concerning technology.

Share this post


Link to post
Snakes said:

Doomworld: Ask a yes or no question, and you get an in-depth discussion concerning technology.


Yeah. Better GTFO if you can't stand the heat. We're fucking hardcore here, bitch. Because Doom is Serious Business 'round here, nigga.

Share this post


Link to post

I just downgraded my Ultimate Doom 1.9 to 1.1 registered.
The timedemo results are very very similar. No improve of performance of a magnitude of 3x or 4x as expected. So, the claim that doom 1.2 or older was using 13h might not be right. Also, the classic appearance of 1/4th stripes which could indicate ModeX, when starting and exiting are here too. The same things with shareware version 1.1 and 1.2.

Though only the heretic tests gets much faster as I explained before. New guess, Doom was always designed with the slow method, Heretic programmers got the source of Doom and thought "why doing it like this? why not regular 13h?" and just rewrote code to never use ModeX because they found it unoptimal.

The only doom version I have managed to benchmark and got better results is doom alpha 05. You can press T and the doom guy revolves around as fast he can and you get an IPS number which I guess is images per second? (I got 200ips in the modern PC with vram max 32bit blit around 200fps). Maybe the engine started as a 13h with fast blit in it's alpha stage and then they did the modex work around even from first shareware or released version.

p.s. I just remembered. There used to be a dos screengrabber which when it grabbed pictures, maybe it also told you what kind of mode is the one it grabbed. It could possibly realize if you are in unchained or not mode. It would be easy to find out with this or similar utility. I'll search my archives.

Share this post


Link to post

For Maes, the linux released assembler functions are for GCC, in otherwords those are linux assembler functions, and linux only, so that still doesn't tell us what DOS really did

EDIT: Whoops yeah it's tasm my bad, but the hexen and heretic rendering functions seem to indicate something different, that a completely different style of functions were used. interestingly enough though, the asm R_DrawColumn and R_DrawSpan in the released sources can also be found in Rise of the Triad

Share this post


Link to post
Guest
This topic is now closed to further replies.
×