The first two sietches now appear to render perfectly.
Bug fixes were needed for the sprite rendering (y-flip was broken…), sprite scaling (don't confuse width, output pitch and input pitch…), the gradient renderer (remember to add gradient y-delta after every line…), and the random number generator that fuzzes the gradient value (remember the RNG state across lines…)
Also two more rooms from the palace, because they're nice!
I've worked out which part of the code fetches lip sync data for the character animations, but the character rendering appears to reach into the UI code so I thought I'd work a bit on that code to get some clarity.
Here's the palace throne room with the ui frieze at the bottom. The interface layout is stored as a list of icon IDs and positions in the executable.
The palace rooms from the intro now render pixel-perfectly, aside from the main characters.
The ready room uses only sprites, but Lady Jessica's and Duke Leto's rooms use polygons and line drawing. The gradient-filled polygons incorporate a random number generator to provide some dithering, and the line drawing code supports stippling.
The attached video shows the rooms being drawn piece by piece.
The first three rooms of the palace now render almost perfectly. There's some off-by-one errors in the polygon rendering code which I'll have to chase down, and there's still an unimplemented line drawing command.
Dune can draw gradient-filled polygons with a bit of noise added to the color, which these rooms don't really show off. Once the code's complete I'll have to validate it byte-for-byte with the original.
This short scene with some lovely palette-only animation consists of a fade-in and two palette transitions.
The palette transitions are driven from a list of callbacks that are run at regular intervals. Dune appears to allow up to 20 functions in the list, but the function to add to the list is only referenced 18 places in the whole game and I doubt much more than two are ever running at the same time.
Finally we get to the first non-video segment of the Dune intro.
This image is constructed of 6 sprites, stored in a 4bpp run-length encoding. Every pixel in the sprites stores a value from 0 to 15 and the caller of the sprite drawing function can then specify a palette offset that the value is added to. Calling it with a palette offset of 255 is how you tell it that you want 8bpp decoding instead of 4bpp.
Dune has a lot of interesting palette-based animation.
The various segments of the intro are defined in a list in the executable, and every segment is defined by two functions, one to loads the fade-in image, and one to play the video or animation.
Oddly, this flying Dune logo part is actually defined as three segments. Segment 1 loads the video and displays the first image, but the play function is an empty function. Segment 2 has an empty load function and then plays 86 frames of the video. The last segment then plays the rest of the video.
The next part of the intro is a clip from intro of the 1984 Dune movie featuring Virginia Madsen as Princess Irulan.
The game includes 10 or so clips from the movie, and to save some space they're compressed at 1/4 resolution, drawn on screen with horizontal and vertical black bars. Strangely you have to dig through the in-game book to find the other videos.
I decoded the first in-game frame from the demo of ReadySoft's "Brain Dead 13" FMV game from 1995.
ReadySoft is best known for Dragon's Lair and Space Ace.
The game runs in 320x200, but in planar made with a frame pitch of 328 pixels (or 82 in plane-pitch…), which isn't fun to wrap your head around, but on the other hand they were nice enough to release the demo with debug symbols!