The first officially released Doom port/enhancement for 3DO
Changelog
Version 0.3
10/12/2023
Performance:
-
More C micro optimizations in all code related to wall segments, visplanes and column or polygon rendering:
Based on some profiler timers around certain functions, I identified some things that would make the C code generate slightly better code. More needs to be done probably in assembly for the next version, but for now I went through the easier route of carefully see what makes C tick. Things like putting things in consts (but not always) or in tight loops using many variables, trying to separate things or rewrite in order to avoid register spillings. This wouldn't be possible to maintain just by looking at plain framerate without tight profiling timings. Sometimes little things like that can give gradual improvements from 0.1fps to 0.5fps at certain very slow player views, but in others you can get 2-3fps more, with all the combined optimizations. It's not too much but it's welcome before I jump into rewritting things in assembly and/or changing my approach and replacing parts of the visplanes with another polygon engine. But for now it's slight improvements that might not there yet.
Rendering:
-
Gamma correction slider:
I managed to use the 3DO's VDLP to affect the translation of 15bpp framebuffer to final 24bpp output. The weird Doom screen setup (320x200 with upper/lower black bars) made this a pain original but with some hacks I managed to make it work. I am also using now the same VDLP mechanism to do a more clean and nice emulation of the screen tinting effects, like red tint when you get hit, green tint when getting the radiation suit, yellow for getting items, invert colors for invulerability, etc. All of these since the original commercial 3DO Doom were done by rendering a big single color CEL quad with blending enabled as an overlay over what was rendered before. It could have tiny effect in the performance when being constantly red or green but I haven't measured this. The hardware supported VDLP that does color translation anyway (with default being a linear 15bpp to 24bpp) is more clean solution for the specific hardware, no extra CEL blending processing over the whole framebuffer. The RGB colorization is combined with the gamma option for the final output.
-
Added fake contrast to walls:
A sector light would apply equally to nearby walls, but it was done differently in the PC version than most console versions. On the PC, besides the default sector lighting, an additional slight increase or decrease would affect 90 degree walls. It gives more depth instead of the blandness in the original. A light feature that doesn't take any performance, just improves the overall visual quality of levels.
-
Liquid warping sectors, RGB rendering enhancements and fire sky:
Not a new feature really, but a reusage of those extra gimmicks from previous versions but this time automatically applied to every map with liquid floors. Read more info on the MOD menu list below.
MOD menu:
-
Added three options to automatically use special effects where applicable:
I used to have some extra gimmicky options like fire sky, colored sectors and distorted floors/ceilings. You would only see these in special cases and not in the main game. I had created my own WADs, also supplied in the release, where I was using extra sector type bits to warp, RGB colorize and more. Now there is a posibility to see those rendering enhancements in the main game or any WAD you load, even without having to edit the special types. If you enable the fire sky, any level that matches the ones of the PS1 that had the fire sky, will also show it (mainly the later hellish levels). The water effects and RGB colorization, will add an extra flare of warpy liquid and nearby color tints around acid, lava and water surfaces. This will happen automatically, if your level or even the original maps had a pool of lava, you will see some nice hellish color tinting around and cool liquid warp effects. It will take a tiny toll on frame rate though, although not most of the times, only when surfaces around are split in such a way that visplanes number get higher than the original. Use these options at your own convenience but be careful on a tiny bit of memory and speed consumption.
Fixes:
-
Flat walls also are RGB colorized now:
Since I added the RGB colorization near liquid sectors, I noticed I hadn't apply the RGB recoloring on the low quality flat walls. Usually not many will prefer the untextured walls, so I didn't bother before, but now it's there. I still haven't done this for the flat or dithered floors though but it's insignificant and will leave it for future versions.
-
Other minor fixes:
When the loading bar appeared, I was flipping through the last frames to update the bar, this would do some ping pong effect on scoreboard or when you die in the screen, not significant but fixed by copying the last from over the previous two before starting the loading bar.
Version 0.2c
24/04/2021
Performance:
-
More micro optimizations in the wall/floor rendering:
I've changed a bit how I do things, much less CEL draw calls, reduced divisions for depth lighting in the visplane rendering, replaced 64bit multiplication with a 32bit one that doesn't overflow. Fixed a long standing bug that make very long walls inaccurate. Could gain 1-2 fps in some heavy player views sometimes.
-
More accurate FPS counter:
One more decimal digit for more accuracy, also previous version would count almost one frame above than reality. This might give the wrong impression that performance has dropped a bit since the last time, but in reality it's the same and improved in few cases because of the wall/ceiling refactoring and micro optimizations.
Rendering:
-
New dithering floor/ceiling mode:
A new rendering mode added to mimick the SNES dithering. This of course only works if you have disabled the texture mapping on the floor/ceiling (lowest floor/ceiling rendering (also called plane rendering now)) and then change the shade options to dithered.
MOD menu:
-
A new rewritten mod menu with scrolltext for help:
A scrolltext starts appearing below the screen, every time the player moves the cursor to a different option. More options added, especially related to the new WAD loader implemented in this version. The first option will let you chose a WAD file in the wads folder. Another option for how strict or relaxed the WAD loader can be. Should it dismiss any IWAD that starts with ExMx instead of the Doom 2 MAPxx (which however is used by 3DO too, regardless if the maps are from Doom 1) or should it map it to the equivalent MAPxx slots on 3DO? Should we not care about missing texture or should we replace with a default texture, or even better map some well known texture IDs from Doom 1/2 to the closest visually from Doom 3DO resources? Finally, some additional options to enable/disable Debug information (all explained in the scrolltext).
Special FX:
-
New sector based special fx:
A lot of new sector effects have been added, but are only available by setting the unused sector type bits. One can make sectors (and nearby walls) have RGB lighting similar to the PS1, enable a fog effect, scroll floor/ceiling sectors in 4 directions, warp the floor/ceiling texture individual, or enable an framebuffer warp effect when the player is inside a sector. These are all demonstrated in some example test WADs I've provided.
Fixes:
-
CD Rom won't start playing if volume at zero:
I think I had fixed that, but if volume is at zero and then a level is reloaded because you reached the exit or died (or starting a new game from the main menu) then music start playing again regardless if it's pointless without volume. It would only stop before, if you moved the music volume slider from 0 to 1 and then back. It saves minimal FPS if music is not playing (in the range of 0.3fps, something only observable with the new more accurate FPS counter).
-
Precision bug with very long textured walls fixed:
There was a long standing bug (wrong order of shift operation) that would break the precision of texture walls while the player is moving side by side looking at a wall. This wouldn't be noticable in most levels, but there was a very big wall line segment in MAP20 where the bug was obvious.
Other:
-
Added external WAD loading support:
The new WAD loader is ready! It's not fully implemented of course, won't load any new graphics resources, but mainly the new map data which will replace over the old ones in the same slot. You can try to open Doom1/2 WADs (IWADS or PWADS) and hope for the best. If a WAD has new monster types or triggers that are not supported, they won't appear at all. If the map data use textures or IDs not existing in the original 3DO Doom resources, there will be an attempt to chose the closest ones (at least if WAD loader is in Relaxed mode in the modmenu) based on some Doom1/2 TextureID to 3DO TextureID table data provided (as binary files). Sometimes there will be odd textures here and there but it's better than HOMs. It uses the ones that are closest to what you expect to see, so for example a hellish red brick with the only hellish red brick available on the 3DO resources. This way you can load WADs with unknown textures and they can still chose to use some common 3DO resource textures over, that match well sometimes. However, the WAD loader was originally planned for maps created exclusively with the Doom 3DO resources (a tutorial on how to make your own maps for OptiDoom 3DO will follow in the site).
-
A loading bar:
When a new level is loaded, there is a loading bar. If you enable the Debug information then you can see also the name of the Lumps loaded and the remaining memory. This may be useful when loading big external WADs that might fail to load or crash either because of some bug/bad information in one of the lumps or memory simply exceeded.
-
Added mouse support:
Several mouse control options, either mouse only or different mouse+dpad configuration. Mouse sensitivity sliders and always run option.
Version 0.2b
04/10/2020
Performance:
-
New pixel scaler options:
A better way for a low quality rendering, instead of skipping loops in wall column rendering, simply scale pixels on X and Y by rendering the whole game in half width and/or height window in an offscreen buffer, then render back scaled up to match the original size. This is a bit faster than old method because it halfs also the visplane calculations instead of just skipping rendering half of the columns. Added also a fit to screen scaler, so even if you change the regular size of the game window, you can play at full screen (with some degradation of the pixel size of course). Now,. frame rate is significantly better in heavy player views when matching the resolution and double pixel rendering of other ports.
-
Frame limiter options:
If you found the sudden jump from 30fps when looking at a wall to under 10 when rotating and your view is suddenly far, then I've added more frame limit options at 1 to 4VBLs (60, 30, 20, 15fps for NTSC, 50, 25, 17.5 and 12.5 for PAL systems). There is also a vsync option which can have sudden jumps but reduces a flickering issue when using scalers at higher frame rates. The flickering in the scaler modes is unavoidable else, because I scrapped the 4th offscreen buffer because of memory issues. There is also an unlimited option added for benchmarking purposes (don't try it for regular play, it's unstable and also flickers a lot).
Rendering:
-
Graphics presets options:
In addition with the new scaler modes, I added a generic list of graphics presets with a preselection of the performance and rendering options so that you find something suitable to your needs without bothering to fiddle with individual options. There are some joke modes like Atari, Amiga and super blocky min, while others try to recreate the original screen size and quality of some systems (like SNES, GBA and Jaguar). For example, when you reduce the window size to something closer (but not exactly as I couldn't match the precise resolution but in number of pixels the closest option) to GBA or SNES, while on SNES the preset automatically disables floor texturing but keeps depth shading (which is off in GBA version), both using the 2x1 pixel scaler (as most console ports really doubling pixel on X, unlike the 3DO version with full pixel res) then you see the 3DO is unfairly judged, when most other ports were rendering a smaller real size Doom window but scaled on X. There is also the default 3DO option, max 3DO size and quality (pretty slow) and a Custom option which if you change values and select another preset and back, it retains the values (the others will reload the default). One can experiment with the best options or select on of the presets that balances rendering/speed for their tastes.
MOD menu:
-
New options to help release some memory:
Some of the testers on our 3DO discord, noticed there are some locking issues as resources are reloaded/released from CD-Rom. When memory is very low, opening a door that results into new sectors on the BSP tree appearing, the original Doom would suddenly load sprite resources for the new things/enemies in view on demand (even if they are not visible on the final rendering, but visible in the BSP tree in the subsectors). This creates some problems like these when memory is low (but still it seems few hundred kbs are ready, but might be misleading). So, to ease things, I added options in the modmenu to disable some effects that need memory like the New Skies or the Gimmick Effects that don't affect gameplay. One can even reduce the number of visplanes from 64 to 32 or in between. In my tests, visplanes don't usually exceed 16-20, rarely hit 30, and the visplane structure takes some more memory. You can safely have it at something like 32 or 40 or whatever, in the worse case scenario I added a check that stops adding visplanes if max limit is reached (instead of a crash/reset of the game) and may get HOMs at far distance (but I haven't encountered it happen,. noclipping and far outside could reach 27-33 visplanes at worst and there is the safe mechanism to even prevent crash when it happens this time). If you set everything off, visplanes to 32 and not load PSX sound fx (which take a bit more memory) E1M1 starts with 660k while 64 visplanes and other options on would get 560k (of course these values lower and change variably as you move through the level).
Special FX:
-
Feedback effects:
Since I had to implement the screen scalers using the CEL hardware texture feedback capabilities, I thought it would be cool to use it for other effects. From the rather useless but impressive Doom running on every side of a cube (3 visible at each frame), to splitting the screen into grid quads and distorting the vertices, while mapped on the actual Doom game screen, producing an impressive realtime framebuffer distortion effect (could be used for an underwater level in the future). Finally average blending with the previous screen produces a motion blur effect. These effects allocate few extra geometry meshes and other stuff, so they are optionally enabled in the mod menu if you just want to experience them.
Fixes:
-
While noclip, player could still trigger linedef actions:
Normally when noclipping, you shouldn't activate teleportation, raising/lowering of platforms or doors and ending the level. I noticed this would happen in the previous version, fixed it.
-
More precise average colors for untextured walls/floors:
Previously when using the untextured low quality walls/floors, I'd lazilly pickup the first color of the palette of each texture and use it as a single color. In few cases this created odd colors (most of the texture could be a brown bring, but the texture would be black for example, because of some darker dirt between the bricks). This time I precalculated by average each pixel color of every texture and store back for later retrieval. Some brighter colors but more consistent to the original texture feeling.
-
No damage from acid floor while bringing up the menu:
Previously, when bringing up the menu while in game, would pause the gameplay but player would still be inflicted damage if standing over a damaging sector (usually acid/lava/etc). From looking at the code, more action might have been fixed, like your radiation suit or other bonus depleted, while you were casually searching options, etc. Now,. just about everything gameplaywise is paused when the menu is on (except the animated flat textures which are on the rendering anyway).
Other:
-
FPS options changed to Stats:
Revolving through the options, you can show only FPS, FPS and Memory left (one value is how many time low memory was hit and a callback to purge all resources was called), and finally visplanes on view and max visplanes so far in level. Those are also good for debugging but I included them in the released game as they are interesting and others could maybe investigate if something goes too low or high at a place.
Version 0.2
04/08/2019
Performance:
-
Untextured wall quality option:
A new wall quality option that renders a fully untextured wall. It's more like retro 3D, but can be fun to navigate and improves speed a bit although not much. Combined with the new shading options, it either looks like gouraud or flat shading.
-
Depth shading options:
A new option that will improve performance quite well in some cases. Simply disabling the light diminishing by depth, in walls and floors. The alternative options are to always select brightest(closest) or darkest(furthest) shade. This will btw disable the smooth depth shading through the whole rendering, not the individual sector lighting, so you can still have darker areas or glowing/blinking areas, the enviromental lights that made Doom great are still there, they are just not shaded by Z anymore. This means few things, less calculations are happening per scanline (horizontal or vertical), but also there is pretty good performance improvement in the case of untextured and unshaded floors/ceilings as I can avoid a CPU intensive step in the Doom rendering only for this case. Sluggish player views that would be 8-9fps would go 12-14fps at some cases for example.
-
New wall CEL quad renderer:
The first attempt to totally replace the original Doom column renderer with one more proprely using the CEL engine, by trying to draw a full wall segment with a full quad polygons, or at least breaking it into sub quads when there is tiling involved, is completed! I had few tricks in my sleeve which failed, trying to avoid vertical tiling (works on emulator but freezes on real 3DO) that could have won more performance, but I took some steps back and have to subdivide tall walls vertically too. You can have a door that fits perfectly a full texture drawn with 1 single CEL, instead of several columns masquared as CELs, and then a wall that has to be split horizontally to 10-20 CELs because it's repeating tiled on X and Y. So,. performance is a hit and miss, but there is some good improvement when rendering stairs (some stair views would go from 8-9fps to 11-12fps) and at worse case scenarios (when walls are too far and most could be rendered with very few columns anyway, instead of going for full polygon which is more costly for so small width, in which case I render some of the far away walls with original Doom columns) the frame rate is the same or maybe very rarely 1fps less with original Doom. In other cases I am +1 or +2 fps, and when going close to some walls there is more improvement (but at these cases the frame rate was already good enough, over 15fps and gaining +5 fps, or sticking your face in a wall will go from 40fps to 52fps in some cases). The new renderer works with texture alignments and offsets, you will notice some differences because of non-perspective correct, but not as bad, some views look better (there are innacuracies in the original column renderer too), some close wall views look more distorted.
-
Implemented depth shading for the wall CEL quad renderer:
The original version was unlit, not shaded by distance (but still shaded by sector lighting) as there is no column renderer to individually setup each CEL for each column with different shading value. There is nothing like gouraud shading in the CEL engine, but only flat shading for the entire polygon. But since many walls in 3DO Doom have a shorter width (32 or 64 instead of 128) to fit in memory, I realized the walls are more frequently subdivided than I thought. And so I could still shade each individual CEL, producing something like flat shading by distance, a bit more choppy, but still does the work if you want the shading on but prefer the polygon renderer.
-
A lot of tiny optimizations and refactoring
The way even the original Doom pipeline worked has been refactored in a way to reduce calls per individual wall column and try to do few of the calculations outside of the wall column or floor/ceiling span loop. It's still pretty have but I think it did a tiny improvement on things (starting E1M1 with original performance options goes from 8fps to 9fps) and made the code easier to read and manipulate. Also, a lot of refactoring with all these different performance options that make things more complicated, so it's an ongoing process as I add more stuff.
Rendering:
-
Things shading options:
This was easy to add and doesn't waste performance. Have you noticed that in many cases, enemies and things are pretty bright in the original? Also, the player weapon doesn't shade when you walk in darker sectors. This is all changed with the new option that shades everything based on where they standing. You will see some lit up monsters go darker as they walk in shadow!
-
Wireframe mode:
This is just added as a gimmick but also a nice way to observe scene visibility. It simple renders walls as wireframe and stops rendering floors or skies. Sprites are still occluded by walls, so that costly extra wall rendering pass that will mark for flats/sky/sprite occlusion is still there, so performance is better but not stellar. But it's much fun to go through Doom this way!
Gameplay:
-
New Player/Enemy speed options:
Is Player 2X too fast to control? Then have an in between 1.5x option if you still want to go a bit faster. How about some slower but not frozen in time monsters? Then 0.5x will feel like you are in The Matrix!
MODs:
-
PSX sound effects:
In a mod menu right at the beginning, you can select to replaced the sound effects with the PSX ones. It can only happen at this moment in the very beginning and not later in game because of some memory allocation issues. Also, it's still experimental, as I've noticed some serious slow downs at later levels (CD loading constantly to allocate and then destroy objects as memory is tighter with the PSX sound effects). So, use it at your own risk, if you want just to try it, but if you plan to finish the entire game without problems be warned, although in such case you can always reset the game and select the normal sound effects and the level progress will be restored anyway.
Fixes:
-
Extra Blood particles improved:
In the previous version they were behaving like missiles, so when they sprayed the player or enemies, you will hear them screaming in pain even though no damage was done. Also, as most of the particles would hit walls sometimes, many of them would die without making an appearence. I have added a new flag MF_PARTICLE when I create them, which I handle a bit different than MF_MISSILE, so now they always appear and you can bath on them without blocking them or making that ouch player sound. This means, they are also more visible and cool when using fists or chainsaw. And I could reduce their spawned number a bit because everyone of them is visible and too many of them would slow down things at impact.
-
Small fixes in the options menu:
If you enabled some cheats or other player relevant options (like fly mode) and then exited a level, the player variables would reset but not the menu option switches, so you would see noclip still enabled on the menu while it's disabled in the next level (you also have to reenable it, finishing a level resets player state).
-
Stop CD audio playing when music volume is zero:
No need to even run the music player if volume is zero obviously. Might improve tiny performance or frame drops when CD is hard to read. Thanks Versus!
Version 0.1
10/12/2018
Performance:
-
Wall quality:
Halfing the columns horizontal resolution gives little improvement (maybe 10-20%). Even more (40%) when you select the faster but buggier version (can't find a way to avoid the visplane spills at the moment, maybe next release)
-
Floor quality:
Option for flat(untextured) floor/ceiling quality (just like SNES). Simply by refusing to run the software renderer on the visplanes, you end up with a minimalistic look that at least saves important speed if there are a lot of visplane pixels to cover. A test map with lowest ceiling possible and endless big room, where the majority of the screen is covered by floors/ceiling surfaces, from 10fps gave 20fps by enabling this option. That's the ideal case though.
-
Enable CEL clipping:
There is a super clipping in the hardware that be default is off, to speed up when rendering CELs are outside the screen. Since the original code doesn't seem to clip the wall columns against the screen in the CPU, that results in some severe slow downs when the player stuck his view towards some really tall walls. Just by adding these flags in the CELs (CCB_ACSC, CCB_ALSC) but also enabling it in the hardware, the speed when your look is very close to a wall increased (it's the same as sticking your view in a short wall now).
-
FPS counter:
Added the option to display an FPS counter. This way you can check the performance at various stages of the player view and decide for yourself how much the above options improve performance.
Rendering:
-
Map lines thickness:
This is just a nice easy gimmick I added. It looks good sometimes. It enabled thicker (pseudo antialiased, kinda cartoonish) lines in the automap. Can drop performance in the automap especially in later levels when there are too many linedefs.
-
New sky rendering:
You can choose between a lighter set of sky gradients (Day, Night, Dusk and Dawn) or the might fire sky from PSX Doom!
Gameplay:
-
Enable cheats:
Why having to tap the original 3DO sequence of buttons (not as easy to remember as IDDQD or IDKFA :) to enable a cheat? I have added a menu where the cheats are disabled but you can enable the weaker and stronger (cheatier) of them as you move the slider. The weaker cheats are automap options (show all items, full map lines, and everything) and a proper NoClip option (that didn't even exist in the original cheats). The stronger cheats are simply IDDQD and IDKFA. The original way to apply a cheat (button tapping) is still preserved (and enabling a cheat this way will also switch on the options in the menu). Oh, also the locked extra screen modes are enabled by default (no need to hide them under a cheat anymore).
-
Player Speed:
You can chose normal speed (1X) and double speed (2X) where you move twice as fast (but hard to navigate) and your weapons also shoot twice as much!
-
Enemy Speed:
That's a pretty fun switch to play with. Do you want double speed monsters (2X) for some challenge? Or set the enemy update to pause (0x) so that you move around without nuisance, or do your Matrix moves! It's funny to pause things, shoot the paused enemies and then unpause to have them all at once die. Or pause while fireballs are in midair and hover around closely a stopped Imp fireball or something. It's like time stop!
-
Extra Blood:
This is experimental but pretty much fun. I simply spawn way more blood puffs and give them random velocities around X,Y and Z. Could break Doom if there are many monsters maybe, basically in rare occasions sprites disappear and reappear when the particles are spawned, but there could be more issues in later levels I just haven't got the time to test. I will improve in these functions in the future and add different kinds of particles. Use it at your own risk!
-
Fly Mode:
That's a pretty cool function I wanted to add, maybe it can be an alternative to NoClip if you happen to fall into an inescapable pit of acid (there are few of them even in the original Doom maps). But it also allows you to fly up high in places you couldn't reach and have a unique view of how Doom levels look from above. It steals the controls from Left/Right Pad when enabled (replacing strafe with fly up/down).