My current solution to the rendering in WME is rather slow, capping out at around 30 fps on my i7, which means I get lower frame rates in Dirty Split than I do in Diablo III. The major difference between the two would of course be partially explained by Dirty Split being rendered entirely in software. But that alone shouldn’t excuse a non-changing 2D scene not managing to get more than 30 fps.
Now there are a few places that the rendering can be improved: First of all, is there any reason to redraw the screen if NOTHING has changed? Probably not. Is there any reason to produce as many frames per second as possible, maxing the CPU-load? Probably not.
So, I put in a framerate cap, for the time being this is capped at 25 fps, to keep my CPU from maxing (and thus my laptop from getting quite hot). In practice it should probably go a bit higher than that, but since the rendering itself limits it’s possibility at the moment, that discussion is rather moot.
To get the rendering to go a bit smoother, I had to detect if the new frame was at all different from the last frame, and preferably also WHAT was different from the previous frame, and then only redraw the parts that were changed. (The “dirty rectangles”)
The old renderer
Originally, all surfaces that wanted to be rendered would apply a scale to themselves and then pass the scaled surface to the renderer (the surfaces would also cache the last scale, to avoid reapplying the scale every frame if it was only drawn at one size). Every frame would start off with clearing the screen-buffer, then drawing the surfaces one by one. Thus there was almost no difference between drawing a very different frame, or the same frame again, as all the surfaces would need to be redrawn anyhow.
Replacing this means I have to take care to keep the same behaviour intact, which means:
- Any area that was drawn last frame, but isn’t drawn now needs a redraw
- Any area that doesn’t get anything drawn in it, should get filled with the clear-colour (which was originally drawn into the screen-buffer on clear anyhow)
- If any element was drawn before element X, it still needs to be redrawn before element X if it needs to be redrawn.
- If any element was drawn after element X, it still needs to be redrawn before element X f it needs to be redrawn.
Render-tickets
- First, the list of render tickets is purged of all items that were drawn last frame, but did not receive requests for draw this frame.
- The dirty rect is filled with the clear-colour
- Any tickets that intersect the dirty rect get’s that section redrawn
- Finally the back-buffer is copied to the screen buffer and onto the screen.
Issues
Other developments
Current engine status
- Graphics: 80-90% Works completely, but is very slow
- Sound: 50-60% Works, but lacks volume-control and WAV-file support
- Fonts: 70-80% Works fine, but is a bit darker than in the original, also no solution is in place for replacing system-fonts (that won’t necessarily be available on non-Windows-platforms)
- PPC-support: Can’t guess at a number, but the engine starts, and seems to run OK
- Video: Works, but has the same issues as Broken Sword 2.5 lists, video desyncs from audio, and is very slow
- Savegames: 80-90% Currently broken by a mis-setting of version-numbers, but that should be a quick fix, otherwise works fine, and has no noticed memory-leaks/issues.
- Renaming to ScummVM-convention: 40-50% would be my estimate, but I would guess at closer to 40 than 50.
- Sprite mirroring: 100%