I hope that whoever at Google decided on these values is suitably embarrassed.
Thomas Fach-Pedersen
@madmoose
For the night attack scene in the game intro, Dune uses a particle system with very gnarly assembly code in it.
They freely treat registers as either 16-bit values or a pair of 8-bit values, first treating the 8-bit parts as signed values, then rotating and shifting bits in the whole 16-bit register. I haven't worked out the meaning of it yet, but I've mostly replicated it, at least.
Here's a video of my in-progress Rust replica, until it crashes :-)
fn main() { let mut machine = machine::Machine::new();
let (dos, mut ctx) = machine.get_dos_and_context(); dos.exec_load_and_execute(ctx, "DNCDPRG.EXE"); } ```
Thomas Fach-Pedersen
@madmoose
I struggled for a while with architecting my emulator in Rust. In an emulator it’s easy to end up with a network of objects that all want to mutably call each other, which Rust will fight you on.
I ended up with a simple `Machine` struct that owns all the parts (CPU, memory, devices, dos, etc.), and using a split borrows method to separate out the parts needed. When I need to call a method on dos, a method on Machine splits out the dos and a dos context, which I can pass around.
Thomas Fach-Pedersen
@madmoose
Another day, another amazing concert! This time the fantastic French-born Chilean rapper Ana Tijoux at Alice in Copenhagen.
Next week, it’s The Flaming Lips, who usually put on extraordinary shows.
Thomas Fach-Pedersen
@madmoose
Bob Hund gave a fantastic performance in Christiana tonight! Initially it was supposed to be one night, their last concert in Denmark, but they sold out three nights.
Thomas Fach-Pedersen
@madmoose
Good news and annoying news!
Good news: I decoded the lip sync data from the audio voc files.
Annoying news: The lip sync data only controls the lips, not the rest of the face…
I see the rest of the face being drawn but I need to work out what data is controlling it and how it's timed… Cryo didn't do anything the easy way.
Here's your father, Duke Leto Atreides, telling you, his son, “I am the Duke Leto Atreides, your father”.
In the demo version of Cryo's Dune, Feyd-Rautha Harkonnen was based on a production image of Sting from the Dune movie, but was redesigned before release.
Here's a video of the image of Sting, Feyd-Rautha from the demo version, and the final portrait from the game.
(Let's see how Mastodon handles a very wide video…)
I decoded the face animations from Dune, mostly based on the fantastic description by Henrik Persson on his blog on zwomp.com.
They're a list of animations, each a list of frames, each a list of image groups, each a list of images. An impressive 4 levels. In the CD version, the VOC-files contain lip-sync ids that reference this data, but how exactly they match up is TBD.
I can only upload one video per toot, but I'll make a web viewer for these soon.
They're a combination of a position and an offset stored in the bitmap cast member, and a position in the score. I’ll have to triple-check against some screenshots of the original before moving on.
The transparency on the fairy is hacked, next up is grabbing that from the proper flags.
I think the only relatively easy task left in this little game intro is sound, before I have to tackle scripting…
Apparently Director stores height before width. Along with a bit of hacked scaling, things look slightly better, although image placement is still off in other places.
I've been trying to get a grasp on the Macromedia Director format, in an effort to help out on ScummVM’s support of the format. Following what I consider the sound principle of "you can't understand it unless you do it yourself", I've been making a basic decoder which can now dump images from, at least, one game: Ivanoff Interactive's Magnus og Myggen. I haven't yet done anything that ScummVM can't do, but I'm learnink! #scummvm#ReverseEngineering#macromediadirector
Cryo's Dune excels at using palette manipulation to set the mood. Dune uses 4 palettes for every day (morning, day, dusk, night), and cycles through 32 palettes every 8 days.
Here's the outside of the Atreides palace in all 32 sky palettes. (Hopefully it survives whatever Mastodon does to the image)
The game transitions the palette smoothly but fairly quickly when the time of day changes. That might be worth a video…
@codingstyle started looking into the file PRT.HNM from the floppy version of Dune, which didn't seem to be a video file. After he worked out where Dune loaded the file and saw that it was hardcoded to load the first 58 bytes, I was, after a bit of tinkering, able to extract all 29 frames.
Chris worked out that PRT must be short for Protection, because these are the images that Dune makes you find in the manual for copy protection.
They're uncompressed, but some files are sprite sheets with multiple images.
The full screen images are stored in planar mode and the sprites in interleaved mode.
One quirk is that color 0 (black) is used for transparent pixels and color 8 (dark gray) is remapped to black instead.
Thomas Fach-Pedersen
@madmoose
From “Captain Blood” by ERE Informatique/Exxos (1988).
Yet another little RLE compression algorithm – the EGA planes appear to be stored in the opposite order from Purple Saturn Day.
Thomas Fach-Pedersen
@madmoose
I noticed (in an old LGR video) that the background stars in Exxos’ Purple Saturn Day looked very similar to the stars in Cryo's Dune – yes, I've been staring at Dune for too long…
Cryo was formed when the team behind the Exxos label left ERE Informatique in 1989.
Naturally I started looking at decoding the image files. The first file I decoded was the Exxos logo, which uses a simple RLE-compression. Sadly it appears to be the only image encoded in that format, so more digging is needed…
Thomas Fach-Pedersen
@madmoose
Digging through the Dune executable I came across the functions and definitions that make up the results screen.
Dune supports interpolated strings, where variables are substituted in based on escape codes, but here the strings are loaded in and the default values are simply overwritten in memory.
The bottom frieze isn't correct for the results screen but it does show off the cute little date and time indicator… 🙂
There's probably no line in any game – indeed, any written media – more deep, powerful, or weighty than the first in-game spoken line from Cryo's Dune:
"I am the Duke Leto Atreides, your father."
The lip sync system isn't hooked up properly yet, but here's all the lip sync frames for your enjoyment.
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!
The sprites are exported to png with alpha transparency.
I got tired of hacking my engine every time I wanted to inspect something more closely…
Not all the sprite sheets have a palette so some of them will export in grayscale. Also, there's no way to tell if a resource is a sprite sheet. I'll probably include a list.
It took a while but I finally found where Dune draws the talking heads. This is 9 sprites put together.
The game builds a list of the sprites (still working on how), and if I copy the list from my emulator, “Duke Leto, your father” show's up.
I spent a long time on how the game reads the lip sync data that's in the .voc-files, but Dune completely ignores that when audio is not enabled – and my emulator doesn't have audio yet…
I reverse engineered the globe rendering code a good while ago, and finally decided to integrate it into the engine.
There's a couple of lookup tables, some pre-calculation, and a bit of 16.16 fixed point math. Luckily reverse engineering it doesn't mean you have to understand how it works!
This video also highlights the need for a rescaler from the non-square pixels of 320x200.
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.