View Full Version : San to PNG guide (How The Dig cinematics video was made)

05-21-2007, 04:28 AM
From http://mojoart.mixnmojo.com/

This video The Dig Cinematics is a high quality video which contains many cinematics "cut-scenes" from the game The Dig. Big thanks goes to the man who made the recording, Stefan Sundin. Thanks man! :)

The download:
The Dig Cinematics.mp4 [14:30 Min, 38.4MB, 800x600, High quality]

Streamed version at Google Video [14:30 Min, 21MB, 320x240]

Most screen recording programs record cut-scenes in LEC games with stutter in my experience. And how did he do it? How did he record/extract the cut-scenes from The Dig with video getting so smooth? I asked for if he could do some sort of a guide, so others could perhaps make more excellent smooth videos from scumm games. And here is the guide:


So, you want to be able to convert .san files to formats readable by other programs?
Here I'll show you how to convert the .san files to .png and .ogg, which can easily be converted into other formats.
I already assume you know how to edit source code, compile it, so this tutorial requires a certain degree of technical skills.
I used Linux (Ubuntu) all the way, I guess all these things would work in Windows as well, though I haven't tested it at all.
I'll use ScummVM [scummvm.org] version 0.9.1 in this tutorial, as well as ScummVM Tools.

First off we want to extract the video from the .san files, to do that we're going to use ScummVM's own smush player.
Get the ScummVM source code [http://prdownloads.sourceforge.net/scummvm/scummvm-0.9.1.tar.bz2?download] and extract the contents of the archive to a directory.
Now we're going to dig into the code, these are the files we're going to mess with:

'smush_player.cpp' is the file which handles the processing of smush movies.
We are going to enable some code in this file that output each frame processed to a png file.
To do this, open the file with an editor and put this code before the first '#ifdef DUMP_SMUSH_FRAMES' (line 54):
const char myparentdumpdir[]="/home/user/Desktop/sanfiles"; //Change this to your location, note that this directory must exist!
char mydumpdir[255];

'#define DUMP_SMUSH_FRAMES' will enable the code which dump each frame to its own png file, unfortunately, there is a little problem, a part of the code isn't working anymore (this code has probably not been used in some time, so it shouldn't be expected to be entirely compatible anymore).
The particular broken part is the call to '_vm->getBaseName()' in the function 'SmushPlayer::updateScreen()'.
To fix this we will replace this line:
sprintf(fileName, "/path/to/somethere/%s%04d.png", _vm->getBaseName(), _frame);
sprintf(fileName, "%s/%04d.png", mydumpdir, _frame);
That will try to create the png files in the directory specified by the mydumpdir variable, which is in turn dependent on the myparentdumpdir variable.

Now we must add the code which handles the mydumpdir variable and create the directories where the png files are then written.
We will add this code to the function 'SmushPlayer::play', which is the function which is called when a smush movie is played: (line 1318)
// Prepare for framedumping
sprintf(mydumpdir, "%s/%s", myparentdumpdir, filename);
char makemydir[255];
sprintf(makemydir, "mkdir %s", mydumpdir);

Now we've setup the code which output the png images, this will happen with every smush movie which is played.
With these modifications you could just start playing and as soon as a smush movie is played, it will output a png image for every frame.
Of course, we wan't to be able to convert files by just specifying the .san files, to do this we will edit 'script_v6.cpp'.
In this file we want to edit the function 'ScummEngine_v6::o6_kernelSetFunctions', from here we can start a smush movie by just specifying the filename.
E.g., by calling 'sp->play("DARKCAVE.SAN")' we will tell the smush player to play the smush movie DARKCAVE.SAN.
Anyway, append this text to the function: (line 2530)
// Convert these files
char *filestoconvert[] = {"ALCOVE.SAN", "ASTTUN.SAN", "DARKCAVE.SAN", "M1.SAN", "M2.SAN", "NEXUSPAN.SAN", "PIGOUT.SAN", "RTRAM1.SAN", "RTRAM2.SAN", "RTRAM3.SAN", "RTRAM4.SAN", "RTRAM5.SAN", "SKY.SAN", "SQ10.SAN", "SQ11.SAN", "SQ12A.SAN", "SQ12B.SAN", "SQ13.SAN", "SQ14B.SAN", "SQ14SC04.SAN", "SQ14SC07.SAN", "SQ14SC11.SAN", "SQ14SC14.SAN", "SQ14SC16.SAN", "SQ14SC19.SAN", "SQ14SC22.SAN", "SQ15A.SAN", "SQ15B.SAN", "SQ17.SAN", "SQ18A.SAN", "SQ18B.SAN", "SQ18SC15.SAN", "SQ19A.SAN", "SQ19B.SAN", "SQ19C.SAN", "SQ2.SAN", "SQ3.SAN", "SQ4.SAN", "SQ5.SAN", "SQ6.SAN", "SQ6SC3.SAN", "SQ7.SAN", "SQ8A1.SAN", "SQ8A.SAN", "SQ8B.SAN", "SQ8C.SAN", "SQ9.SAN", "TOMBDWN1.SAN", "TOMBDWN2.SAN", "TRAM1.SAN", "TRAM2.SAN", "TRAM3.SAN", "TRAM4.SAN", "TRAM5.SAN", '\0'}; //SQ1.SAN
int i=0;
while (filestoconvert[i] != '\0') {

This code will loop through the variable 'filestoconvert' and play each file until it hits an element containing '\0' (this should be the last element).
The files specified here are all the .san files from The Dig except SQ1.SAN, I didn't include this file since it's the opening sequence in the game, and it will start automatically, you probably want to change this variable to the .san files you want to convert.

Now you've edit all you need in the source code, and now it's time to compile it, more help on this is available online on ScummVM's wiki [http://wiki.scummvm.org/index.php/Compiling_ScummVM].
Make sure you got all the dependecies for ScummVM + libpng.
Enter a prompt and go to the directory with the scummvm source.
We must tell the compiler to include the libpng sources, to do this type:
export LDFLAGS="-lpng"
Now we can build the makefiles, type:
If no errors has occured, type:
Now you should be able to run scummvm by typing:

Now you should have been greeted with the normal ScummVM GUI, just setup your game and press 'Start' to make the conversion process happen.

Now that you got your pretty lossless .png frames, I guess you want audio as well?
You can extract the audio with ScummVM Tools, I used version 0.9.0 [http://prdownloads.sourceforge.net/scummvm/scummvm-tools-0.9.0.tar.bz2?download].
The specific tool we want to use is 'compress_scumm_san', if you want you can just compile the tools and use it as-is and get either a Ogg Vorbis or MP3 audio file.
I want a file which is as perfect as possible so I'll edit the source, 'compress_scumm_san.cpp', to disable the creation of the .ogg/.mp3 file and disable the deletion of a perfect .wav file.

Anyway, open up 'compress_scumm_san.cpp' and go to line 860.
Here you'll see the lines:
if (_waveTmpFile) {
sprintf(tmpPath, "%s/%s", outputDir, inputFilename);
if (_oggMode)
sprintf(tmpPath, "%s/%s.wav", outputDir, inputFilename);

Change that to this:
if (_waveTmpFile) {
/*sprintf(tmpPath, "%s/%s", outputDir, inputFilename);
if (_oggMode)
sprintf(tmpPath, "%s/%s.wav", outputDir, inputFilename);

That will disable the encoding and deletion of the .wav file.
To build 'compress_scumm_san', just run 'make' in that directory.

Anyway, now you got all you need to mix all this to something similar to my The Dig Cinematics video [http://video.google.com/videoplay?docid=3688586457507659107].

I want to thank the people in #scummvm [FreeNode] to help me with all this, without them I wouldn't have been able to do this at all.
This concludes this tutorial, feel free to email me questions and I would love to hear what you have created with the help of this.

Stefan Sundin