Encoder for Kyrandia 3 VQA files?

Ask for help with ScummVM problems

Moderator: ScummVM Team

Post Reply
Spinoza
Posts: 6
Joined: Mon Sep 28, 2009 5:21 pm

Encoder for Kyrandia 3 VQA files?

Post by Spinoza »

Hi everybody!

Since the support for Kyrandia 3, and the development of a decoder for their VQA cutscene files, I was wondering if any of you had the time and possibility to create an encoder for such files.

Oldgamesitalia.net created a patch for translating the game in Italian (since this game was never published in our country) but faced the impossibility to encode in VQA the video files with the subtitles for the cutscenes.

So my question is the one in the title: has anyone developed such an encoder? And, if so, would he/she be willing to share with us?

Thank you!
User avatar
LordHoto
ScummVM Developer
Posts: 1029
Joined: Sun Oct 30, 2005 3:58 pm
Location: Germany

Post by LordHoto »

There's only this: http://en.wikipedia.org/wiki/.VQA#Encoding_.2F_Decoding

but it may very vell be that the encoder there is aimed at a different VQA version. Kyra3 is using Version 1, which is the only one we support.
Spinoza
Posts: 6
Joined: Mon Sep 28, 2009 5:21 pm

Post by Spinoza »

Yes, we tried that encoder but to no avail (the encoder is aimed at newer versions of VQA files).

Thanks for the quick answer, LordHoto!
micartu
Posts: 15
Joined: Thu Jun 28, 2007 4:00 am

Post by micartu »

More than encoder, a little bit easier hack to do: it's possible to create a workaround like in broken sword 1 that allow to read the subs from an external file like a .txt?
The subs we need to insert are for 2 .vqa:

boat video (Malcolm is talking)
and intro


there is a feature request about it, but it's from 2008, no one patronized it and i guess is almost forgotten.

http://sourceforge.net/tracker/index.ph ... tid=418823

What about something similiar to Broken Sword1?
micartu
Posts: 15
Joined: Thu Jun 28, 2007 4:00 am

Post by micartu »

An idea from a friend:
the results will be a file .txt with the same name of the .vqa movie. If the txt is present, it will be loaded in memory. In that file will be present:

beginning frame
final frame
subtitle

only one line for subtitle.

Maybe we could get inspiration from the subtitles for borken sword1 "sword1/animation.ccp"

the object/variable is _movieTexts

But it won't be difficult open a file and insert all inside an array.

Now we can go to modify the file kyra/vqa.cpp

in the function open

bool VQAMovie::open(const char *filename)

i would insert subs opening and loading, and in the "play" their visualization.

void VQAMovie::play()

then before to do

_screen->updateScreen();

i would make it stamp at video the sub of the current frame, using the function:

_screen->printText(const char *str, int x, int y, color1, color2);

how i can say wich one is the current subs?

Tha variable "i" of the cycle "for" contain the current frame, so it would be enough to search between the lines wich line belong to the current frame (if there is one).

to make an exemplification (it's not code):

bool VQAMovie::open(const char *filename) {

if filename.txt exist, load sub in the array subtitles
}



void VQAMovie::play() {

//codice vario

for (uint i = 0; i < _header.numFrames; i++) {

//codice vario

subtitle_to_visualize = search in the array sub the current subtitle

width_sub = _screen->getTextWidth(subtitle_to_visualize);

_screen->printText(subtitle_to_visualize,
(320-width_sub) / 2, 180,
0xFF, 0xFF);

_screen->updateScreen();

}

}

the getTextWidth is needed only to calculate the coordinate x where it must be stamped the sub to be centered.
Coordinate Y could be 180 (20 pixel from the bottom of the screen should be ok).
The only uncertainty is if it's necessary to define first a font (but maybe it's already defined).

The function to search the line to be visualized for the frame, can be done in a way like this:

for (uint i=0; i < lenght_array_sub; i++) {
if ( (frame_current >= frame_beginning) &&
(frame_current<= frame_ending) )
subtitle_to_visualize = subtitles;
}

Ah, obviously in the function close must be deallocated in the used memory for the subtitles array.

It will be necessary a little bit of time to do some tests (i don't believe it will work at the first attempt) and write a little bit of code. the only thing that block me is that i've no experience in compiling scummvm (i don't know what i need to compile it... like external library etc.).



That is a raw translation. in the next post i'll post the original italian text. What do you think about it Lordhoto?
Do you have any advice? It could work for you?
micartu
Posts: 15
Joined: Thu Jun 28, 2007 4:00 am

Post by micartu »

original version in italian:

brevemente l'idea è questa.
Cercare un file col nome del VQA ma .txt, se esiste, lo si carica in
memoria.
In questo file si può mettere

frame inizio
frame finale
sottotitolo

Una riga per sottotitolo.

Magari si può prendere ispirazione dai sottotitoli per broken1.
sword1/animation.cpp

l'oggetto/variabile è _movieTexts

Ma non dovrebbe essere difficile aprire un file e mettere tutto dentro
un array.


A questo punto si va a modificare il file
kyra/vqa.cpp

Nella funzione open

bool VQAMovie::open(const char *filename)

metterei apertura e caricamento dei sub, e nella play la loro
visualizzione

void VQAMovie::play()

dopodiché prima di fare

_screen->updateScreen();

stamperei a video il sub del frame corrente, usando la funzione

_screen->printText(const char *str, int x, int y, color1, color2);

Come faccio a sapere qual è il sub corrente?
La variabile i del ciclo for contiene il frame corrente, quindi basta
cercare nelle righe quale riga (se c'è) è del frame corrente.

Per fare una semplificazione (ma non è codice):

bool VQAMovie::open(const char *filename) {

se esiste filename.txt, carica i sub nell'array sottotitoli
}



void VQAMovie::play() {

//codice vario

for (uint i = 0; i < _header.numFrames; i++) {

//codice vario

sottotitolo_da_visualizzare = cerca nell'array sub il sottotitolo
corrente

larghezza_sub = _screen->getTextWidth(sottotitolo_da_visualizzare);

_screen->printText(sottotitolo_da_visualizzare,
(320-larghezza_sub) / 2, 180,
0xFF, 0xFF);

_screen->updateScreen();

}

}

la getTextWidth serve solo a calcolare la coordinata x dove stampare
il sub in modo che sia centrato.
La coordinata Y potrebbe essere 180 (20 pixel dal fondo dello schermo
dovrebbero andar bene).
L'unica incognita è se serve definire prima un font (ma forse lo è
già).

La funzione per cercare la frase da visualizzare per il frame, si può
fare più o meno così

for (uint i=0; i < lunghezza_array_sub; i++) {
if ( (frame_corrente >= frame_inizio) &&
(frame_corrente<= frame_fine) )
sottotitolo_da_visualizzare = sottotitoli;
}

Ah, poi ovviamente nella funzione close va deallocata la memoria
utilizzata per l'array dei sottotitoli.

Come vedi, bastano le basi del C++, non è roba complessa, ma serve
tempo per fare prove (non credo che funzioni al primo colpo) e
scrivere un po' di codice. E la rottura un po' di scatole è anche
riuscire a compilare lo ScummVM, che non sempre va a buon fine,
bisogna scaricare librerie aggiuntive e qualcos'altro.
User avatar
LordHoto
ScummVM Developer
Posts: 1029
Joined: Sun Oct 30, 2005 3:58 pm
Location: Germany

Post by LordHoto »

The general idea is clear, what you friend posted looks like the logic from Sword1 (or was it 2?). If your friend needs help in compiling ScummVM, we have a wiki page for that over here.
Post Reply