Last week was quite productive for me: I optimized engine startup performance, fixed a number of bugs, and started a work branch for a significant refactoring.
I started the week by doing an investigation into performance bottlenecks during engine startup. I found two main problems: 1) slow searching of the file tree during locating of game resources, and 2) slow 3D model initialization. In the case of 1), I rewrote the implementation of our StringPool class using C++ and applied a set of smaller fine-tunes. StringPool is a heavily used class in the resource subsystem that stores a set of unique text strings (e.g., file names). Then, I addressed problem 2) by replacing a slow path search routine with an efficient StringPool-based one. Finally, I updated the advancement of the busy mode progress indicator so that it more accurately depicts the real progress of the startup. These optimizations caused a significant reduction
in startup times.
One nice new feature I added is the apropos
console command. For instance, if you're looking for a particular command or variable but can't quite remember its name, apropos
can be used to print all commands, variables, aliases, and games whose name contains the specified text. For instance: apropos dev
It became apparent that the earlier change to enforce the "one sound per object" rule wasn't working quite as intended. For instance, the Cyberdemon alert sound was cut off by its footstep sounds. After a bit of investigation I noticed that the Sound priorities defined in the .ded files were being ignored. Now only sounds with a lower priority are considered eligible for stopping due to overlap -- if a higher priority sound is playing, a lower priority one will not get started at all. This should match the original behavior more closely. Let us know if you spot obvious error cases in the sound behavior.
On the bug fixing front I managed to do the following:
- Fixed drawing of high-resolution menu background pictures (e.g., jHRP background).
- Serious problems when msg-show set to 0: at startup, caused a crash due to a cvar change notification; at runtime, caused GL state mismanagement.
- Fixed crash when binding an artifact shortcut.
- Unix: Expansion of ~ in file paths (e.g., with -iwad).
The plan for this week is to continue with my next big refactoring task: replacing the SDL-based application core with Qt. This is not a simple swap: SDL currently heavily influences window management, OpenGL initialization, and input event reception. The goal here is to write revised Qt-based code for this functionality and get rid of the old SDL-based and Win32-specific code. Early results with mouse events are quite positive: there will be support for horizontal mouse wheel events in addition to vertical ones, we have full control over when the mouse gets grabbed or not, the window should be dynamically resizable, and the SDL joystick code still seems to work even though the app is not running the SDL event loop. However, I will need to write new platform-specific code for display mode/resolution changes, as that is not covered by Qt.
Last week I mostly spent my time doing preparatory clean up and refactoring ahead of beginning work on my next big refactoring task: replacing Doomsday's map representation with the ideas developed in my old map-cache research branches.
In order to support the signifcant new features we have planned for version 2.0 (in particular the new world renderer
) it is patently necessary to replace the map representation entirely. One of the key factors for the new design is the removal of all encumbrances effected by the need to support doom.exe mapping tricks. However before this work could begin we would first have to address the issue of the engine's (and games') dependence on third-party tools used during the transformation of the id tech 1 map data format into something suitable for Doomsday's use.
The first phase of this transformation, the internalization of a BSP node builder (based on glBSP 2.24), was achieved during the (then named) 1.9.0-beta development phase. Now that the engine is in control of the BSP generation process we can be sure that the data we build upon conforms to our expectations.
The second phase of this transformation, the immunization of the games' play simulation logic from decisions made during map translation, was completed for the 1.9.7 release. This process involved replacing structures such as the blockmap
(which previously was loaded from the archived map format) with sanitized data the game implementations could rely upon.
As some of you will be aware (particularly long time DOOM map authors) there are certain inherent design caveats and various tricks that can be employed using these data structures. Support for those tricks is presently missing but will be re-introduced at some point during the 1.9.x series.
With the foundations laid we can now begin the process of transforming our internal map data representation. The first phase of this work, a partial redesign of our BSP node builder is where I plan to focus my effort over the coming week.