30/12/2006 @14:05:12 ^14:54:24

I'm only making this post because it's two weeks since the last one and that's probably too long. Not much worth writing down here has happened, unless you want to hear about how I split the automap code in rboom into three different files and tidied it up.

I'd be surprised if anybody can* even read this, because my connection is acting up. Of course due to my chronic fear of the telephone and their bad reputation for customer service, I am reluctant to call ntl about it. I don't know what to do.

I did the usual family visit on Boxing Day which wasn't as bad as I was expecting, I guess the cousinishes are getting a bit older and are slightly less annoying. Plus this year I wasn't horribly sleep-deprived which helped. They've acquired this enormous fluffy tomcat from somewhere, which I tried and somewhat succeeded to make friends with.

I haven't played any new wads recently, instead I tried to do both the Memento Mori megawads again, each level from scratch. MM was successful but there are a few maps in MM2 that I haven't done yet and probably won't for one reason or another. For instance, MM2 19, which has a couple of bits near the end that always kill me (the descending platform is a bitch) and it takes 30 minutes or more of careful play to even get that far. Good recipe to give up from loss of patience.

Oh yes I'll just mention there was a new version of blofeldx.wad released a month or two ago. It fixes many of the problems I had with it a year ago - the monsters in the floors have gone, the trooper in the air duct on map05 can be shot from the side now without having to use rocket splash damage, and the author has done a new skill level with a more normal monster distribution which I think improves the gameplay. I couldn't fathom the cyberdemon at the start of map02 though. You don't have to kill it, it gets teleported off somewhere else, where you can see it, but it's stuck! I don't know. Also there's a manual door on map02 (sector 427) which is repeatable on one side but not the other and you can get into all sorts of strife with it having two thinkers running on it at once, one trying to open it, the other trying to close it. This is really an engine bug but it is pretty daft to have one side of a door repeatable and the other not as you can get stuck.

* I'd be surprised if anybody chooses to read this, but that's a different matter

16/12/2006 @21:42:16 ^23:12:47

it would be oh!

so nice

I made an advent calendar out of bottles of alcopops

Not that much to write about. Very few new maps played, and anyway I'm kind of sick of writing reviews of them. This is mostly because it takes ages as I feel compelled to write far too much.

The reason I haven't played many maps is that I've been coding something called LineInfo. It's a rewrite of the line specials processing system based on a big table of function pointers and data. It's very much neater than huge switch statements full of the same code repeated over and over again, and also allows the easy solution of two major classes of ZDoomisms. Of course complaining about ZDoomisms is 50% of my reviews so I don't know what I'll be able to say now!

Rewriting the line specials processing is a good way to find lots of hilarious bugs in it. I've already written about the raise ceiling to highest adjacent special. Also:

I've contributed a couple of bug fixes to PrBoom and PrBoom-plus, in particular changes to the build system, which uses autoconf. I was pretty pleased that it appeared to work, as autoconf can be very difficult. It's not conceptually difficult but there are an awful lot of macros and things to know and it seems very hard to work out the right way to do what you want to do with it.

I finally know exactly why monsters can open locked doors, when their reverse side isn't locked! (e.g. when speedrunning map27 you use the archvile to open the red door at the end) The monster tries to move by a number of map units equal to its speed, every tic. If this move is blocked by any lines, and any of these lines are special lines, it will unconditionally activate all of them, including the reverse side of the door that isn't locked. Furthermore it doesn't do a side check, so it can activate lines that are facing the wrong way. Pretty weird huh?

I'm also going to do map28 for CC3. For this I'm going to finish off Sector 14, the map I started after I finished Elixir. I decided to do this and started work months ago, but didn't say anything in case I changed my mind. However, people were claiming all the free slots so I thought I should get one before they ran out. Please note the map's name has been changed to Token Archvile because the Sector 14 joke is too old now.

05/12/2006 @22:27:39 ^22:52:06

Regular/Extended CeilingRaiseToHighest is really screwy!

Note: I wrote this originally for Doomworld but decided to turn it into a site update. Of course nobody'll see it here but oh well!

Consider the four line specials that purportedly raise a ceiling to its highest surrounding ceiling. These are 40 (W1) 151 (WR, Boom) 166 (S1, Boom) and 186 (SR, Boom). The reason they're screwy is because they sometimes try to start undocumented floor effects as well, and do it in a highly inconsistent and frankly incomprehensible way that smacks of bugs and poor testing.

40 W1 Raise Ceiling to HEC

Let's start with the only one that works in Doom, the W1 type. The code, from linuxdoom-1.10/p_spec.c, is this:

case 40:
  // RaiseCeilingLowerFloor
  EV_DoCeiling( line, raiseToHighest );
  EV_DoFloor( line, lowerFloorToLowest );
  line->special = 0;
  break;

What happens is, the rising ceiling is started, then a lowering floor is attempted on the same sector. This fails because Doom doesn't allow two actions simultaneously on the same sector.

In Boom (and thus PrBoom, MBF, Eternity etc.) this was changed to the following:

case 40:
  // RaiseCeilingLowerFloor
  if (demo_compatibility)
  {
    EV_DoCeiling( line, raiseToHighest );
    EV_DoFloor( line, lowerFloorToLowest ); //jff 02/12/98 doesn't work
    line->special = 0;
  }
  else
    if (EV_DoCeiling(line, raiseToHighest))
      line->special = 0;
  break;

"Aha," said the Boom developers. "We can make this thing work as it was originally intended, now that we can handle simultaneous floor/ceiling actions. But we must preserve the original behaviour for old demos."

The thing is, they didn't. Notice the test at the top of the block, for demo_compatibility. This should be* if (!demo_compatibility) ! The sense of the test is inverted. Why bother trying to start a floor action in a compatibility mode that doesn't support simultaneous floor and ceiling actions? This has to be a typo - you could miss out all the lines from the if to the else and the code would have the same effect.

* Of course this mistake was a blessing in disguise in a way - allowing a floor action on Doom's linedef type can cause problems in maps that weren't designed for it. Consider for example sectors 330/334 of MAP16 in Memento Mori II, in the self-building room beyond the blue door. The window ledges would lower down to the ground outside, and you could fall out and get stuck.

166/186 - S1/SR Raise Ceiling to HEC

On we go. These only exist in Boom, so there's no demo_compatibility to worry about. However, here's the code for the S1 type*:

case 166:
  // Raise ceiling, Lower floor
  // 166 S1 EV_DoCeiling(raiseToHighest), EV_DoFloor(lowerFloortoLowest)
  if (EV_DoCeiling(line, raiseToHighest) ||
      EV_DoFloor(line, lowerFloorToLowest))
    P_ChangeSwitchTexture(line,0);
  break;

The intention here again is that pressing the button will cause both the ceiling to rise and the floor to lower. However, notice the use of the double-bar shortcircuit operator. This means that if the ceiling raise succeeds - that is, there isn't already a ceiling action in progress on that sector - the floor lowering will not happen.

Therefore for the S1 type the floor will need to be lowered by another line somewhere else. The SR type can be made to lower the floor, by pressing it twice in quick succession! But - it gets worse - if you allow the ceiling to complete its rise, the button will lose its ability to make the floor lower!

I believe this bug is the result of another typo - the double-bar shortcircuit operator should be the single-bar, non-shortcircuiting version, so both functions are executed regardless of the success of the first one.

* The code for the SR type is identical except the second parameter to P_ChangeSwitchTexture is 1, indicating the line is repeatable. It's not relevant to this discussion.

151 WR Raise Ceiling to HEC

This is the only one that works as you'd expect it to! It just raises the ceiling and lowers the floor without any messing about. However having said that the floor behaviour - as for all of these four line specials - is undocumented in boomref.txt, so maybe in fact it is just as wrong as the rest of them...

Conclusion

Don't use these line specials if you can avoid them. I feel they poorly implemented, extremely inconsistent in their behaviour, and probably weren't tested very well. Use the generalised versions which don't mess around with the floor. Passuse lines can be used to make a switch that starts two actions at the same time. Or you could use Szymanski's Splitdoor for DOOM2.EXE, which works in vanilla.