Thomas Fach-Pedersen
@madmoose

All the particles finally appear to go the right places, only the palette transitions are missing.

(The original is on the left, my reimplementation is on the right.)

The code contain wonderful little bit-shuffling snippets like this to calculate particle positions, which'll never really be "Clean Code" :)

```asm
seg000:0B9A xchg dl, dh
seg000:0B9C rol dh, 1
seg000:0B9E and dx, 1FFh
seg000:0BA2 cmp dx, 320
```

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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 :-)

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

Sometimes you just have to step through it line by line…

Thomas Fach-Pedersen
@madmoose

The goal of Chani is to be a time-travel debugger for DOS games.

Just a regular debugger with proper snapshot-and-restore support would be a big help, and it’s easy to dream up future features!

Thomas Fach-Pedersen
@madmoose

And now my Rewrite-it-in-Rust emulator Chani runs Dune :)

Thomas Fach-Pedersen
@madmoose

```rust
impl Machine {
pub fn get_dos_and_context(&mut self) -> (&mut Dos, DosMachineContext<'_>) {
let dos_context = DosMachineContext {
cpu: &mut self.cpu,
devices: &mut self.devices,
memory: &mut self.memory,
};
(self.dos.as_mut(), dos_context)
}
}

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”.

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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…)

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

Here's a programmer-designed wasm interface to show all the portrait animations from Dune: thomas.fach-pedersen.net/dune/

They play too fast but at least you can see them all!

These little wasm visualizers are very fun to make! (aside from the UI-part)

Here’s my interactive Dune globe visualizer thomas.fach-pedersen.net/dune/ and my Dune room viewer (which has a nice UI!) thomas.fach-pedersen.net/dune/

I also made a wasm video viewer that only shows the Irulan intro video for now: thomas.fach-pedersen.net/dune/

Thomas Fach-Pedersen
@madmoose

Cryo drew up three different sietch leaders and then tried to disguise them with different hair cuts and beards. Here's one of them:

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

Here’s for-legal-reasons-not-Sting beautifully animated.

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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.

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

Sprite positions look like they work now.

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…

#reverseengineering #macromediadirector

Thomas Fach-Pedersen
@madmoose

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.

#reverseengineering #macromediadirector

Thomas Fach-Pedersen
@madmoose

The images are not showing up in the right places, but they're showing up, and that's good enough for tonight.

#reverseengineering #macromediadirector

Thomas Fach-Pedersen
@madmoose

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

Thomas Fach-Pedersen
@madmoose

I could spend a long time on these…

Thomas Fach-Pedersen
@madmoose

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…

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

I ported my room renderer for Cryo’s Dune to Rust and WASM, clearing up a lot of bugs in the process.

Hover over the image to highlight the different sprites and polygons! Go out on the balcony and change the sky palette!

(Some rooms are blank but that's not a bug.)

Source code: github.com/madmoose/dune-rust

My Dune globe renderer is also still available escaping to a hostile desert planet sounds enticing: thomas.fach-pedersen.net/dune/

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

@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.

#reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

Exxos’ last game was “Kult: The Temple of Flying Saucers” aka "Chamber of the Sci-Mutant Priestess” from 1989 with music by @StephanePicq

I made an extractor for the 16-color EGA graphics: github.com/madmoose/exxos-kult

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… 🙂

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

Cryo's Dune displays its text in variable-width fonts with justified text layout. It has two fonts for latin scripts and two for Fremen.

When you choose the Fremen language, Dune just uses the French localization with this custom font 🙂

The fonts are in the resources DNCHAR and DNCHAR2. Each store a table of 256 glyph widths, followed by 128 8x9 glyphs and 128 8x7 glyphs.

(Font extraction has been added to dune-extract)

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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.

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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!

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

I made a quick utility in Rust to extract resources and sprites from Dune's DUNE.DAT: github.com/madmoose/dune-extra

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.

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

Here's a visualization of the non-moving parts of Leto's face.

The placement of the face sprites are defined in the last block of the sprite sheet file, in this case LETO.HSQ.

The data defines a number of facial expressions (each a list of sprites-id, x, and y), and a number of facial expression sequences.

I’m still working out how exactly these interact, but the first list appears to be all the static parts.

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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…

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

"The planet is Arrakis, also known as… Dune."

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.

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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.

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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.

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive

Thomas Fach-Pedersen
@madmoose

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.

#dosgaming #retrogaming #reverseengineering #dune #CryoInteractive