I actually managed to do Lucas Arts lipsync... Only about 100 lines of code.
It's designed to parse pamela files. (although you have to rename the extension or AGS gets confused)
feel free to give it a try but its not the cleanest code in the world.
int SpeechTimer = 0;
struct SyncFrame{
int time;
bool played;
String phoneme;
};
SyncFrame SyncFrames[50];
function ResetSyncFrames(){
int i = 0;
while (i <50){
SyncFrames[i].played = false;
SyncFrames[i].time = -1;
SyncFrames[i].phoneme = "";
i++;
}
}
function TalkFrame(String Phoneme){
if (Phoneme == "T") return 6;
if (Phoneme == "L") return 13;
if (Phoneme == "UH1") return 20;
if (Phoneme == "IY0") return 6;
if (Phoneme == "P") return 20;
if (Phoneme == "R") return 21;
if (Phoneme == "K") return 23;
if (Phoneme == "S") return 15;
if (Phoneme == "IY1") return 6;
if (Phoneme == "IH1") return 6;
if (Phoneme == "END") return 0;
return 0;
}
function iSay(this Character*, String what){
ResetSyncFrames();
if (what.StartsWith("&",false)){
int firstspace = what.IndexOf(" ");
String strnum = String.Format("%s",this.scrname);
strnum = strnum.Substring(1, 4);
strnum = strnum.Append(what.Substring(1, firstspace - 1));
String filename = String.Format("%s.dat",strnum);
//Display("%s",filename);
File *PamFile = File.Open(filename, eFileRead);
if (PamFile != null){
bool processing;
int index = 0;
while(!PamFile.EOF){
String line = PamFile.ReadRawLineBack();
if (processing && !line.StartsWith("//")){
int colon = line.IndexOf(":");
if (colon > 0){
String strtime = line.Substring(0, colon);
SyncFrames[index].time = strtime.AsInt / 15;
SyncFrames[index].phoneme = line.Substring(colon + 1, line.Length - colon - 1);
// Display("%d;%s",SyncFrames[index].time, SyncFrames[index].phoneme);
}
index ++;
}
if (line == "[Speech]") processing = true;
}
PamFile.Close();
}
}
this.SayAt(50, 50, 200, what);
SpeechTimer = 0;
}
function DoSpeechChecks(){
if (cLydiaTalk.Speaking){
int i = 0;
while (i < 50){
if (!SyncFrames[i].played && SyncFrames[i].time == SpeechTimer){
cLydiaTalk.LockViewFrame(10, cLydiaTalk.Loop, TalkFrame(SyncFrames[i].phoneme));
SyncFrames[i].played = true;
i = 60;
}
i++;
}
SpeechTimer ++;
}
}
function repeatedly_execute_always()
{
DoSpeechChecks();
}