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!
Encoder for Kyrandia 3 VQA files?
Moderator: ScummVM Team
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.
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.
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?
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?
An idea from a friend:
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?
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?
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.
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.