Ticket #8162: lipsync.diff

File lipsync.diff, 4.7 KB (added by SF/dschepler, 18 years ago)

Lip sync patch

  • scumm/script_v8.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/script_v8.cpp,v
    retrieving revision 2.127
    diff -u -r2.127 script_v8.cpp
     
    15941594                break;
    15951595
    15961596        case 0xDA:              // lipSyncWidth
     1597                push(_sound->voiceLipSyncWidth());
     1598                break;
    15971599        case 0xDB:              // lipSyncHeight
    1598                 // TODO - get lip sync data for the currently active voice
    1599                 // HACK - return random values for now, to make things look half decent
    1600                 push(_rnd.getRandomNumber(255));
     1600                push(_sound->voiceLipSyncHeight());
    16011601                break;
    16021602        case 0xDC:              // actorTalkAnimation
    16031603                {
  • scumm/sound.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
    retrieving revision 1.74
    diff -u -r1.74 sound.cpp
     
    4141        _musicBundleBufFinal = NULL;
    4242        _musicBundleBufOutput = NULL;
    4343        _musicDisk = 0;
     44        _voiceLipSyncData = NULL;
     45        _voiceLipSyncLength = 0;
    4446        _talkChannel = -1;
    4547}
    4648
     
    11831185        }
    11841186
    11851187        ptr += 12;
     1188        _voiceLipSyncLength = 0;
    11861189        while(tag != MKID_BE('DATA')) {
    11871190                tag = READ_BE_UINT32(ptr); ptr += 4;
    11881191                switch(tag) {
     
    11961199                        case MKID_BE('REGN'):
    11971200                        case MKID_BE('STOP'):
    11981201                        case MKID_BE('JUMP'):
    1199                         case MKID_BE('SYNC'):
    12001202                                size = READ_BE_UINT32(ptr); ptr += size + 4;
    12011203                        break;
    12021204
     1205                        case MKID_BE('SYNC'):
     1206                                size = READ_BE_UINT32(ptr); ptr += 8;
     1207                                _voiceLipSyncLength = size / 4 - 1;
     1208
     1209                                // Some voice has up to 426 entries.
     1210                                if (_voiceLipSyncData == NULL)
     1211                                        _voiceLipSyncData =
     1212                                                new _lipSyncEntry[512];
     1213                                if (_voiceLipSyncLength > 512)
     1214                                        error("Too much lip sync data: %d entries",
     1215                                              _voiceLipSyncLength);
     1216
     1217                                for (int i = 0; i < _voiceLipSyncLength; i++) {
     1218                                        _voiceLipSyncData[i].jiffies =
     1219                                                READ_BE_UINT16(ptr);
     1220                                        _voiceLipSyncData[i].width = ptr[2];
     1221                                        _voiceLipSyncData[i].height = ptr[3];
     1222                                        ptr += 4;
     1223                                }
     1224                        break;
     1225
    12031226                        case MKID_BE('DATA'):
    12041227                                size = READ_BE_UINT32(ptr); ptr += 4;
    12051228                        break;
     
    12171240       
    12181241        byte * final = (byte *)malloc(size);
    12191242        memcpy(final, ptr, size);
     1243
     1244        // Needed for lip sync in COMI
     1245        _voiceBundleStartTime = _scumm->_system->get_msecs();
     1246
    12201247        if (bits == 8) {
    12211248                return _scumm->_mixer->playRaw(NULL, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
    12221249        } else if (bits == 16){
     
    12251252                warning("Sound::playBundleSound() to do more options to playRaw...");
    12261253                return -1;
    12271254        }
     1255}
     1256
     1257Sound::_lipSyncEntry *Sound::voiceLipSyncData() {
     1258        int jiffies = (_scumm->_system->get_msecs() -
     1259                       _voiceBundleStartTime) / 17;
     1260
     1261        if (_voiceLipSyncLength == 0) {
     1262                warning("Attempt to get lip sync data from sound with none");
     1263                if (_voiceLipSyncData == NULL)
     1264                        _voiceLipSyncData = new _lipSyncEntry[512];
     1265                _voiceLipSyncData[0].width = 0;
     1266                _voiceLipSyncData[0].height = 0;
     1267                return _voiceLipSyncData;
     1268        }
     1269
     1270        // Use a binary search to find the last entry with time
     1271        // <= current time.  Invariant: current time is in [left,right)
     1272        int left = 0, right = _voiceLipSyncLength;
     1273
     1274        while (right - left > 1) {
     1275                int mid = (left + right) / 2;
     1276                if (_voiceLipSyncData[mid].jiffies == jiffies)
     1277                        return _voiceLipSyncData + mid;
     1278                else if (_voiceLipSyncData[mid].jiffies > jiffies)
     1279                        right = mid;
     1280                else
     1281                        left = mid + 1;
     1282        }
     1283        return _voiceLipSyncData + left;
    12281284}
    12291285
    12301286int Sound::playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned) {
  • scumm/sound.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/sound.h,v
    retrieving revision 1.25
    diff -u -r1.25 sound.h
     
    6060        int32 _outputMixerSize;
    6161        int32 _bundleSampleChannels;
    6262
     63        uint32 _voiceBundleStartTime;
     64        struct _lipSyncEntry {
     65                uint16 jiffies;
     66                uint8 width, height;
     67        };
     68        _lipSyncEntry *_voiceLipSyncData;
     69        int32 _voiceLipSyncLength;
     70        _lipSyncEntry *voiceLipSyncData();
     71
    6372        File *_sfxFile;
    6473        uint32 _talk_sound_a1, _talk_sound_a2, _talk_sound_b1, _talk_sound_b2;
    6574        byte _talk_sound_mode;
     
    167176        void bundleMusicHandler(Scumm * scumm);
    168177        void stopBundleMusic();
    169178        int playBundleSound(char *sound);
     179        uint8 voiceLipSyncWidth() {
     180                return voiceLipSyncData()->width;
     181        }
     182        uint8 voiceLipSyncHeight() {
     183                return voiceLipSyncData()->height;
     184        }
     185
    170186        byte * readCreativeVocFile(byte * ptr, uint32 & size, uint32 & rate, uint32 & loops);
    171187        int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned);
    172188        int playSfxSound_MP3(void *sound, uint32 size);