You Just Nest It
void (*f)(void);
This is a pointer to a function that doesn't return anything.
What if I want to make a function that takes no argument and returns such a pointer?
Let's call it getfunc, and suppose it takes no argument itself (so it's basically getfunc(void))
As the title suggests, you just nest it. See the f:
void (* f )(void);
f is a variable of the type you want the function to return. So, replace f with the function.
void (*getfunc(void))(void);
I've always wondered how you do that without typedefs. I always had this idea it was impossible, for some reason.
source
sloccount
According to sloccount rboom has fewer than three thousand lines over the original source release. When I say I have deleted so much code that I am surprised the thing is still a Doom engine, I am not joking. (Figures for comparison: linuxdoom 36k, rboom 39k, PrBoom 58k)
Indoor City
This wad is not on /idgames but on Doom Wad Station. As the author explains, he likes really huge, massive architecture, and so do I so I downloaded it and took a look. I was not disappointed - this map is ridiculous. It also gives you loads of ammunition, loads of room to run around, and then just throws monsters at you, which is the best thing.
It says it is for ZDoom but it mostly worked in rboom. However it does need jumping and mouselook to get 100% as far as I can see, and even with that there are a few apparently unkillable monsters. Also the health and weapon placement is a bit silly - there's no way you'd ever pick up all those megaspheres, so they are pointless.
In summary, I thought I'd found a gem - quite roughly made, even ugly, yet incredibly fun (a bit like Assaryth) - but it was not to be.
Link: http://www.doomwadstation.com/ndoorcity/
A tale of two GCC warning options, one successfully enabled in rboom, one not.
-Wshadow
This warns about variables that "shadow" others in outer scopes. In principle this could be a good idea, but in practice it isn't so useful, because it's too sensitive and complains about things you don't care about. It complains about everything possibly shadowed, from variables in outer blocks, to global functions defined in header files that you didn't even know existed.
My favourite example was that including math.h defines functions with hilariously generic names like "y0" and "y1". Imagine trying to write any code that deals with coordinates without eventually using such names...
-Wstrict-prototypes
void blah();
This is not a strict prototype as it does not define the parameters of the function. It requires quite a bit of work to make a doom engine strict-prototypes-clean. There are two major cases:
thinkers
Each thinker on the thinker list has its function pointer called every gametic. This is how the game world updates itself. There are lots of different kinds of thinkers - monsters, flashing lights, moving floors etc. - processed by different functions. An example - say, a moving floor - is a struct with a thinker embedded at the start.
All the explicit thinker functions - T_Floor, T_LightFlash, T_VerticalDoor and so on - have their own signatures. They all return void but take different structs (floor_t, lightflash_t, vldoor_t respectively) However, all these have a thinker struct embedded at the start, and the thinker function determines the type of the block in which it is embedded, in a form of run-time type information.
To make these strict we must make all the thinker functions have the same signature, void blah(thinker_t *), and at the start of each function, cast the thinker back to the type with which the function is guaranteed to be called.
code pointers
DeHackEd calls them code pointers, the game source calls them several things, action functions, actor functions, whatever. They're all named A_Something anyway. There's a big table of all the states a mobj can be in and when a mobj enters a state with a code pointer the function is called.
Unfortunately the state table is overloaded to contain both functions for mobjs (which take a pointer to the mobj) and for player weapons (which take a pointer to the player and a pointer to something called a pspdef)
In order to make these strict you have to convert all the code pointers to have the same signature; this is most easily done as taking a pointer to a mobj, since most of them are that way. The player weapon code pointers are passed a pointer to the mobj associalted with the player, which contains a pointer back to the player, in which you store extra information to recover the corresponding pspdef. Thus from a mobj pointer we can recover both parameters needed for the function, or bail out if the mobj is not a player.
The Eternity Engine, from which I stole the idea and some code, calls this "code pointer unification". It's also one less way for a DeHackEd patch to crash the game severely.