Well, I'm going to dust this thing off because people have complained that my main blog has become entirely too tech-heavy, and I'm moderately inclined to agree with them. After a long hiatus, I actually _am_ working on the Scoped project again, believe it or not, and things are coming along quite nicely--farther than they did the last time I worked on it.
The network layer at this point is entirely gone, which means the code is very light and fast--at this point, we're well under 200k for the compiled Release executable, and there's plenty of room to go. Much of the work thusfar has been unifying the CL_ and SV_ systems and their competing data structures. I've combined both the edict_t and the entity_t into a new super-entity_t, and the sv, svs, cl, and cls structures have been rolled into two structures, a game_state_t for game-wide information, and a player_t for player-specific information (things that need to be wiped across level changes and such). The entire engine also dynamically allocates memory through malloc(), free(), new, and delete, getting rid of that clunky Hunk_ system. Since no memory allocation happens in any speed-critical sections of the Quake source, I'm not sure why this Hunk system was written in the first place--it may have something to do with systems design in the days of DOS, something I know admittedly nothing about. I've only just started touching the rendering system, and the most substantial addition there is the first full-on C++ class to hit the engine, an OpenIL texture loading class, which has already brought in high-resolution status bar, console, and text, with more on the way.
As you might have gathered by the OpenIL move, the next round of big code changes will be taking the platform layer out of the code entirely and abstracting it off into OpenAL for sound, OpenIL for images, and SDL for OpenGL framework, input, windowing, etc. The only things it looks like I'll have to totally code up from scratch are the event pump (I need both the ability to add events to a queue to be popped off later and the ability to push an event through to its listeners immediately, something that the SDL event system doesn't give you) and a high-resolution timer (which I'll have to figure out how to implement on Linux, for the time being I can fall back on the SDL 1ms timer).
Anyway, the main point of this post was to get down some ideas I'd been having about how to abstract the entity interfaces a little bit. I think the first thing to do is split out the parts of the entity structure that the renderer needs to know about into a separate structure, which will provide some level of entity-API-independence to the renderer, by which I can add fields to the entity structures without introducing any changes in the renderer module. The entity class can expose a GetRenderParams() accessor that will drop out a RenderParameters structure containing everything the renderer needs to know about drawing the entity. The renderer draws lists of these instead of entities (i.e. gs.visedicts (the old cl_visedicts) becomes a std::vector of RenderParameters structures). Of course, I need to be careful about how I work that--that's speed-critical code inside the PVS-checking algorithms, and I don't want to call a thousand copy constructors per frame on RenderParameters structures, which wouldn't make any sense at all. There might be a way to do that with a vector of references, if you were allowed to construct such a thing in C++. Given that you aren't, maybe some old-fashioned pointers would make the most sense, even though they do make me cringe. I guess since this is a static data member inside a class that shouldn't go anywhere between the time it's added to a PVS list and that list is drawn, it should be safe enough.
My TODO for the renderer is about nineteen pages long, but the first thing to be done is dynamic video mode switching inside the program. It's less easy than it sounds, given that every texture has to be reloaded and rebound once GL is reset. The proper way to do this is through a TextureManager class, but I haven't had the guts to go retrofit one through the entire renderer yet. Then, though, it's as easy as switching video modes, calling some sort of TextureManager::Rebind(), and you're back in business. Some issues will come up, though, given that some of the paletted skin/texture data that's stored inside the models/BSPs is kept around in a really sketchy manner after the models are loaded (variable sized structures and such squirreling away of data). But that's a problem for well after we've converted to SDL/AL, so it's down the road a little bit.
Okay, I've both procrastinated long enough and written more than enough here, so I'm out to do some actual work (curse having to work on holiday).