[Scummvm-cvs-logs] CVS: residual lipsynch.cpp,NONE,1.1 lipsynch.h,NONE,1.1 Makefile.common,1.3,1.4 README,1.17,1.18 actor.cpp,1.28,1.29 actor.h,1.13,1.14 resource.cpp,1.10,1.11 resource.h,1.7,1.8 sound.h,1.5,1.6
James Brown
ender at users.sourceforge.net
Sat Sep 11 07:10:04 CEST 2004
Update of /cvsroot/scummvm/residual
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15593
Modified Files:
Makefile.common README actor.cpp actor.h resource.cpp
resource.h sound.h
Added Files:
lipsynch.cpp lipsynch.h
Log Message:
Lipsync support by salty-horse. Now rejoice! REJOIIIIICE!
--- NEW FILE: lipsynch.cpp ---
// Residual - Virtual machine to run LucasArts' 3D adventure games
// Copyright (C) 2003 The ScummVM-Residual Team (www.scummvm.org)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "stdafx.h"
#include "lipsynch.h"
#include "bits.h"
#include "debug.h"
#include <cstring>
#include <SDL_endian.h>
// A new define that'll be around when theres a configure script :)
#undef DEBUG_VERBOSE
LipSynch::LipSynch(const char *filename, const char *data, int len) :
Resource(filename) {
uint16 readPhoneme;
int j;
if (std::memcmp(data, "LIP!", 4) != 0) {
error("Invalid file format in %s\n", filename);
} else {
numEntries_ = (len - 8) / 4;
// There are cases where the lipsync file has no entries
if (numEntries_ == 0)
status_ = false;
else {
status_ = true;
data += 8;
#ifdef DEBUG_VERBOSE
printf("Reading LipSynch %s, %d entries\n", filename, numEntries_);
#endif
entries_ = new LipEntry[numEntries_];
for (int i = 0; i < numEntries_; i++) {
entries_[i].frame = READ_LE_UINT16(data);
readPhoneme = READ_LE_UINT16(data + 2);
// Look for the animation corresponding to the phoneme
for (j = 0; j < animTableSize_ &&
readPhoneme != animTable_[j].phoneme; j++);
if ( readPhoneme != animTable_[j].phoneme) {
warning("Unknown phoneme: 0x%X in file %s\n", readPhoneme, filename);
entries_[i].anim = 1;
} else
entries_[i].anim = animTable_[j].anim;
data += 4;
}
#ifdef DEBUG_VERBOSE
for (int j = 0; j < numEntries_; j++)
printf("LIP %d) frame %d, anim %d\n", j, entries_[j].frame, entries_[j].anim);
#endif
currEntry_ = 0;
}
}
}
LipSynch::~LipSynch() {
delete[] entries_;
}
LipSynch::LipEntry LipSynch::getCurrEntry() {
return entries_[currEntry_];
}
void LipSynch::advanceEntry() {
if (currEntry_ < numEntries_)
currEntry_++;
}
const LipSynch::PhonemeAnim LipSynch::animTable_[] = {
{0x005F, 0}, {0x0251, 1}, {0x0061, 1}, {0x00E6, 1}, {0x028C, 8},
{0x0254, 1}, {0x0259, 1}, {0x0062, 6}, {0x02A7, 2}, {0x0064, 2},
{0x00F0, 5}, {0x025B, 8}, {0x0268, 8}, {0x025A, 9}, {0x025D, 9},
{0x0065, 1}, {0x0066, 4}, {0x0067, 8}, {0x0261, 8}, {0x0068, 8},
{0x026A, 8}, {0x0069, 3}, {0x02A4, 2}, {0x006B, 2}, {0x006C, 5},
{0x026B, 5}, {0x006D, 6}, {0x006E, 8}, {0x014B, 8}, {0x006F, 7},
{0x0070, 6}, {0x0072, 2}, {0x027B, 2}, {0x0279, 2}, {0x0073, 2},
{0x0283, 2}, {0x0074, 2}, {0x027E, 2}, {0x03B8, 5}, {0x028A, 9},
{0x0075, 9}, {0x0076, 4}, {0x0077, 9}, {0x006A, 8}, {0x007A, 2},
{0x0292, 2}, {0x002E, 2}
};
const int LipSynch::animTableSize_ = sizeof(LipSynch::animTable_) / sizeof(LipSynch::animTable_[0]);
--- NEW FILE: lipsynch.h ---
// Residual - Virtual machine to run LucasArts' 3D adventure games
// Copyright (C) 2003-2004 The ScummVM-Residual Team (www.scummvm.org)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef LIPSYNCH_H
#define LIPSYNCH_H
#include "bits.h"
#include "resource.h"
#include <list>
class LipSynch : public Resource {
public:
LipSynch(const char *filename, const char *data, int len);
~LipSynch();
struct LipEntry {
uint16 frame;
uint16 anim;
};
LipEntry getCurrEntry();
void advanceEntry();
bool getStatus() const { return status_; }
private:
LipEntry *entries_;
int numEntries_;
int currEntry_;
bool status_;
struct PhonemeAnim {
uint16 phoneme;
uint16 anim;
};
static const PhonemeAnim animTable_[];
static const int animTableSize_;
};
#endif
Index: Makefile.common
===================================================================
RCS file: /cvsroot/scummvm/residual/Makefile.common,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Makefile.common 5 Apr 2004 19:06:44 -0000 1.3
+++ Makefile.common 11 Sep 2004 14:09:42 -0000 1.4
@@ -1,53 +1,54 @@
-OBJS =\
- actor.o \
- bitmap.o \
- blocky16.o \
- costume.o \
- debug.o \
- driver_gl.o \
- engine.o \
- keyframe.o \
- lab.o \
- localize.o \
- lua.o \
- main.o \
- material.o \
- matrix3.o \
- matrix4.o \
- model.o \
- objectstate.o \
- registry.o \
- resource.o \
- scene.o \
- screen.o \
- smush.o \
- sound.o \
- textobject.o \
- textsplit.o \
- timer.o \
- vima.o \
- walkplane.o \
- mixer/mixer.o \
- mixer/rate.o \
- mixer/audiostream.o
-
-DEPS = $(OBJS:.o=.d)
-
-residual: $(OBJS) lua/lib/liblua.a lua/lib/liblualib.a
- $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
-
-.cpp.o:
- $(CXX) $(CXXFLAGS) -MMD -c $(<) -o $*.o
-
-lua/lib/liblua.a lua/lib/liblualib.a: lua-build
-
-lua-build:
- $(MAKE) -C lua
-
-clean: lua-clean
- -rm -f residual$(EXEEXT) *.o mixer\*.o *.d mixer\*.d *~
-
-lua-clean:
- $(MAKE) -C lua clean
-
--include $(DEPS)
+OBJS =\
+ actor.o \
+ bitmap.o \
+ blocky16.o \
+ costume.o \
+ debug.o \
+ driver_gl.o \
+ engine.o \
+ keyframe.o \
+ lab.o \
+ localize.o \
+ lua.o \
+ main.o \
+ material.o \
+ matrix3.o \
+ matrix4.o \
+ model.o \
+ objectstate.o \
+ registry.o \
+ resource.o \
+ scene.o \
+ screen.o \
+ smush.o \
+ sound.o \
+ lipsynch.o \
+ textobject.o \
+ textsplit.o \
+ timer.o \
+ vima.o \
+ walkplane.o \
+ mixer/mixer.o \
+ mixer/rate.o \
+ mixer/audiostream.o
+
+DEPS = $(OBJS:.o=.d)
+
+residual: $(OBJS) lua/lib/liblua.a lua/lib/liblualib.a
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+.cpp.o:
+ $(CXX) $(CXXFLAGS) -MMD -c $(<) -o $*.o
+
+lua/lib/liblua.a lua/lib/liblualib.a: lua-build
+
+lua-build:
+ $(MAKE) -C lua
+
+clean: lua-clean
+ -rm -f residual$(EXEEXT) *.o mixer\*.o *.d mixer\*.d *~
+
+lua-clean:
+ $(MAKE) -C lua clean
+
+-include $(DEPS)
Index: README
===================================================================
RCS file: /cvsroot/scummvm/residual/README,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- README 15 Jun 2004 06:04:32 -0000 1.17
+++ README 11 Sep 2004 14:09:42 -0000 1.18
@@ -1,6 +1,6 @@
-Residual: A LucasArts 3D game interpreter Version: 0.03-CVS
-(C) 2003-2004 The ScummVM-Residual team Last Updated: 26th Mar 2004
--------------------------------------------------------------------------------
+Residual: A LucasArts 3D game interpreter Version: 0.04-CVS
+(C) 2003-2004 The ScummVM-Residual team Last Updated: 11 Sept 2004
+------------------------------------------------------------------------------
What is Residual?
-----------------
@@ -54,10 +54,9 @@
What is the state of Residual?
-------------------------------
-Many features are not yet supported. Cutscenes work, you can interact with
-objects and play at least some of the game.
-
-HOWEVER: It may crash. There is no lighting, menus, save/load, etc.
+Basic gameplay works, including cutscenes. Some of the game is playable,
+but many features are either missing or unstable. There are no menus,
+save/load features, lighting, etc. Crashes are likely.
What are the default keys?
--------------------------
@@ -102,13 +101,14 @@
Credits:
------------------------------
ScummVM-Residual Team:
- James Brown Core developer. ScummVM co-lead dev.
- Pawel Kolodziejski Core developer. SMUSH implemention.
+ James 'Ender' Brown Core developer. ScummVM co-lead dev
+ Pawel 'aquadran' Kolodziejski Core developer. SMUSH implemention
Contributors:
- Daniel Schepler Initial engine code and LUA tweaks.
- Vincent Hamm Various engine code
- Lionel Ulmer OpenGL optimisations
+ Daniel Schepler Initial engine codebase, LUA support
+ Vincent Hamm Various engine code
+ Lionel 'bbrox' Ulmer OpenGL optimisations
+ Ori 'salty-horse' Avtalion Lipsync support
Special Thanks To:
------------------
Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/actor.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- actor.cpp 26 Mar 2004 09:28:13 -0000 1.28
+++ actor.cpp 11 Sep 2004 14:09:42 -0000 1.29
@@ -20,15 +20,19 @@
#include "engine.h"
#include "costume.h"
#include "sound.h"
+#include "lipsynch.h"
#include "localize.h"
#include <cmath>
#include <cstring>
#include "driver_gl.h"
+#include "mixer/mixer.h"
+
+extern SoundMixer *g_mixer;
Actor::Actor(const char *name) :
name_(name), talkColor_(255, 255, 255), pos_(0, 0, 0),
pitch_(0), yaw_(0), roll_(0), walkRate_(0), turnRate_(0),
- visible_(true), talkSound_(NULL), turning_(false), walking_(false),
+ visible_(true), talkSound_(NULL), lipSynch_(NULL), turning_(false), walking_(false),
restCostume_(NULL), restChore_(-1),
walkCostume_(NULL), walkChore_(-1), walkedLast_(false), walkedCur_(-1),
turnCostume_(NULL), leftTurnChore_(-1), rightTurnChore_(-1),
@@ -192,9 +196,7 @@
}
void Actor::sayLine(const char *msg) {
- // For now, just play the appropriate sound if found. Eventually,
- // this needs to handle possibly displaying text, starting up
- // appropriate talking chores, etc.
+ // TODO - Display text
// Find the message identifier
if (msg[0] != '/')
@@ -202,15 +204,33 @@
const char *secondSlash = std::strchr(msg + 1, '/');
if (secondSlash == NULL)
return;
- if (talkSound_) // Only once line at a time, please :)
+ if (talkSound_) // Only one line at a time, please :)
shutUp();
std::string msgText = Localizer::instance()->localize(secondSlash + 1);
std::string msgId(msg + 1, secondSlash);
+
talkSound_ = ResourceLoader::instance()->loadSound((msgId + ".wav").c_str());
+ lipSynch_ = ResourceLoader::instance()->loadLipSynch((msgId + ".lip").c_str());
+
if (talkSound_ != NULL) {
Mixer::instance()->playVoice(talkSound_);
- if (mumbleChore_ >= 0)
- mumbleCostume_->playChoreLooping(mumbleChore_);
+
+ // Sometimes actors speak offscreen before they, including their
+ // talk chores are initialized.
+ // For example, when reading the work order (a LIP file exists for no reason).
+ // Also, some lip synch files have no entries
+ // In these case, revert to using the mumble chore.
+ if (lipSynch_ != NULL && lipSynch_->getStatus()) {
+ talkAnim_ = lipSynch_->getCurrEntry().anim;
+ if (talkChore_[talkAnim_] >= 0) {
+ talkCostume_[talkAnim_]->playChoreLooping(talkChore_[talkAnim_]);
+ lipSynch_->advanceEntry();
+ }
+ } else {
+ lipSynch_ = NULL;
+ if (mumbleChore_ >= 0)
+ mumbleCostume_->playChoreLooping(mumbleChore_);
+ }
}
}
@@ -221,9 +241,13 @@
void Actor::shutUp() {
if (talkSound_) {
Mixer::instance()->stopVoice(talkSound_);
- talkSound_ = NULL;
- if (mumbleChore_ >= 0)
+ if (lipSynch_ != NULL) {
+ if (talkChore_[talkAnim_] >= 0)
+ talkCostume_[talkAnim_]->stopChore(talkChore_[talkAnim_]);
+ lipSynch_ = NULL;
+ } else if (mumbleChore_ >= 0)
mumbleCostume_->stopChore(mumbleChore_);
+ talkSound_ = NULL;
}
}
@@ -353,11 +377,25 @@
lastTurnDir_ = currTurnDir_;
currTurnDir_ = 0;
- if (talkSound_ != NULL && talkSound_->done()) {
- talkSound_ = NULL;
- if (mumbleChore_ >= 0)
- mumbleCostume_->stopChore(mumbleChore_);
- }
+ // Update lip synching
+ if (lipSynch_ != NULL && talkSound_ != NULL &&
+ talkSound_->hasReachedPos(lipSynch_->getCurrEntry().frame *
+ g_mixer->getOutputRate() / 60)) {
+
+ ///printf("Reached beyond frame %d (=pos %d). Playing anim %d\n",
+ // lipSynch_->getCurrEntry().frame, lipSynch_->getCurrEntry().frame *
+ // g_mixer->getOutputRate() / 60,lipSynch_->getCurrEntry().anim);
+
+ if (talkChore_[talkAnim_] >= 0)
+ talkCostume_[talkAnim_]->stopChore(talkChore_[talkAnim_]);
+ talkAnim_ = lipSynch_->getCurrEntry().anim;
+ if (talkChore_[talkAnim_] >= 0)
+ talkCostume_[talkAnim_]->playChoreLooping(talkChore_[talkAnim_]);
+ lipSynch_->advanceEntry();
+ }
+
+ if (talkSound_ != NULL && talkSound_->done())
+ shutUp();
for (std::list<Costume *>::iterator i = costumeStack_.begin();
i != costumeStack_.end(); i++) {
Index: actor.h
===================================================================
RCS file: /cvsroot/scummvm/residual/actor.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- actor.h 25 Mar 2004 15:43:05 -0000 1.13
+++ actor.h 11 Sep 2004 14:09:42 -0000 1.14
@@ -26,6 +26,7 @@
class Sound;
class Costume;
+class LipSynch;
class Actor {
public:
@@ -125,6 +126,7 @@
bool visible_;
bool lookingMode_;
ResPtr<Sound> talkSound_;
+ ResPtr<LipSynch> lipSynch_;
std::list<Costume *> costumeStack_;
// Variables for gradual turning
@@ -149,6 +151,7 @@
Costume *talkCostume_[10];
int talkChore_[10];
+ int talkAnim_;
Costume *mumbleCostume_;
int mumbleChore_;
Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/resource.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- resource.cpp 24 Feb 2004 22:43:32 -0000 1.10
+++ resource.cpp 11 Sep 2004 14:09:43 -0000 1.11
@@ -25,6 +25,7 @@
#include "material.h"
#include "model.h"
#include "sound.h"
+#include "lipsynch.h"
#include "debug.h"
#include <cstring>
#include <cctype>
@@ -67,7 +68,10 @@
Lab *l = new Lab(fullname.c_str());
lab_counter++;
if (l->isOpen())
- labs_.push_back(l);
+ if (strstr(de->d_name, "005"))
+ labs_.push_front(l);
+ else
+ labs_.push_back(l);
else
delete l;
}
@@ -82,11 +86,16 @@
Lab *l = new Lab(fullname.c_str());
lab_counter++;
if (l->isOpen())
- labs_.push_back(l);
+ // Handle the Grim 1.1 patch's datafile
+ if (strstr(de->d_name, "005"))
+ labs_.push_front(l);
+ else
+ labs_.push_back(l);
else
delete l;
}
}
+
closedir(d);
#endif
@@ -142,9 +151,9 @@
if (b == NULL) { // Grim sometimes asks for non-existant bitmaps (eg, ha_overhead)
warning("Could not find bitmap %s\n", filename);
return NULL;
-}
+ }
-Bitmap *result = new Bitmap(filename, b->data(), b->len());
+ Bitmap *result = new Bitmap(filename, b->data(), b->len());
delete b;
cache_[fname] = result;
return result;
@@ -195,6 +204,29 @@
return result;
}
+LipSynch *ResourceLoader::loadLipSynch(const char *filename) {
+ std::string fname = filename;
+ LipSynch *result;
+
+ makeLower(fname);
+ cache_type::iterator i = cache_.find(fname);
+ if (i != cache_.end()) {
+ return dynamic_cast<LipSynch *>(i->second);
+ }
+
+ Block *b = getFileBlock(filename);
+ if (b == NULL) {
+ warning("Could not find lipsynch file %s\n", filename);
+ result = NULL;
+ } else {
+ result = new LipSynch(filename, b->data(), b->len());
+ delete b;
+ cache_[fname] = result;
+ }
+
+ return result;
+}
+
Material *ResourceLoader::loadMaterial(const char *filename, const CMap &c) {
std::string fname = filename;
makeLower(fname);
Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/residual/resource.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- resource.h 22 Mar 2004 11:23:37 -0000 1.7
+++ resource.h 11 Sep 2004 14:09:43 -0000 1.8
@@ -30,6 +30,7 @@
class Material;
class Model;
class Sound;
+class LipSynch;
class Resource {
public:
@@ -102,6 +103,7 @@
Material *loadMaterial(const char *fname, const CMap &c);
Model *loadModel(const char *fname, const CMap &c);
Sound *loadSound(const char *fname);
+ LipSynch *loadLipSynch(const char *fname);
void uncache(const char *fname);
private:
Index: sound.h
===================================================================
RCS file: /cvsroot/scummvm/residual/sound.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- sound.h 25 Feb 2004 08:21:30 -0000 1.5
+++ sound.h 11 Sep 2004 14:09:43 -0000 1.6
@@ -28,6 +28,8 @@
~Sound();
bool done() const { return currPos_ >= numSamples_; }
+ bool hasReachedPos(int position) const { return currPos_ >= position; }
+ int getCurrPos() const {return currPos_;}
private:
int numSamples_, numChannels_, currPos_;
More information about the Scummvm-git-logs
mailing list