Exemplo n.º 1
0
        SoundHandle StartTalkSound(int offset, int b, int mode)
        {
            Stream      file;
            SoundHandle handle = new SoundHandle();
            var         id     = -1;

            if (vm.Game.GameId == GameId.CurseOfMonkeyIsland)
            {
                sfxMode |= mode;
                return(handle);
            }
            else if (vm.Game.GameId == GameId.Dig)
            {
                sfxMode |= mode;
                if (!(vm.Game.Features.HasFlag(GameFeatures.Demo)))
                {
                    return(handle);
                }
                throw new NotImplementedException();
            }
            else
            {
                if (_sfxFilename == null)
                {
                    //                    Console.Error.WriteLine("StartTalkSound: SFX file not found");
                    return(handle);
                }

                // Some games frequently assume that starting one sound effect will
                // automatically stop any other that may be playing at that time. So
                // that is what we do here, but we make an exception for speech.
                if (mode == 1 && (vm.Game.GameId == GameId.Tentacle || vm.Game.GameId == GameId.SamNMax))
                {
                    id = 777777 + _talkSoundChannel;
                    _mixer.StopID(id);
                }

                int num = 0;
                if (b > 8)
                {
                    num = (b - 8) >> 1;
                }

                offset += 8;

                _mouthSyncTimes = new ushort[num + 1];
                file            = ServiceLocator.FileStorage.OpenFileRead(_sfxFilename);
                var br = new BinaryReader(file);
                file.Seek(offset, SeekOrigin.Begin);
                for (int i = 0; i < num; i++)
                {
                    _mouthSyncTimes[i] = br.ReadUInt16BigEndian();
                }

                // Adjust offset to account for the mouth sync times. It is noteworthy
                // that we do not adjust the size here for compressed streams, since
                // they only set size to the size of the compressed sound data.
                offset += num * 2;
                // TODO: In case we ever set up the size for VOC streams, we should
                // really check whether the size contains the _mouthSyncTimes.
                // if (SoundMode == SoundMode.VOCMode)
                //      size -= num * 2;

                _mouthSyncTimes[num] = 0xFFFF;
                sfxMode       |= mode;
                _curSoundPos   = 0;
                _mouthSyncMode = true;
            }

            var input = new VocStream(file, true);

            var iMuseDigital = vm.MusicEngine as IMuseDigital;

            if (iMuseDigital != null)
            {
                iMuseDigital.StartVoice(TalkSoundID, input);
            }
            else
            {
                if (mode == 1)
                {
                    handle = _mixer.PlayStream(SoundType.SFX, input, id);
                }
                else
                {
                    handle = _mixer.PlayStream(SoundType.Speech, input, id);
                }
            }
            return(handle);
        }
Exemplo n.º 2
0
        void PrepareSound(byte[] ptr, SoundDesc sound)
        {
            if (ptr.ToText() == "Crea")
            {
                bool quit = false;
                int  len;

                int offset = ptr.ToInt16(20);
                int code   = ptr.ToInt16(24);

                sound.NumRegions = 0;
                sound.Region     = new Region[70];

                sound.NumJumps = 0;
                sound.Jump     = new Jump[1];

                sound.NumSyncs = 0;

                sound.ResPtr   = ptr;
                sound.Bits     = 8;
                sound.Channels = 1;

                while (!quit)
                {
                    len  = ptr.ToInt32(offset);
                    code = len & 0xFF;
                    if ((code != 0) && (code != 1) && (code != 6) && (code != 7))
                    {
                        // try again with 2 bytes forward (workaround for some FT sounds (ex.362, 363)
                        offset += 2;
                        len     = ptr.ToInt32(offset);
                        code    = len & 0xFF;
                        if ((code != 0) && (code != 1) && (code != 6) && (code != 7))
                        {
                            throw new NotSupportedException(string.Format("Invalid code in VOC file : {0}", code));
                        }
                    }
                    offset += 4;
                    len   >>= 8;
                    switch (code)
                    {
                    case 0:
                        quit = true;
                        break;

                    case 1:
                    {
                        int time_constant = ptr[offset];
                        offset    += 2;
                        len       -= 2;
                        sound.Freq = (ushort)VocStream.GetSampleRateFromVOCRate(time_constant);
                        sound.Region[sound.NumRegions].Offset = offset;
                        sound.Region[sound.NumRegions].Length = len;
                        sound.NumRegions++;
                    }
                    break;

                    case 6:     // begin of loop
                        sound.Jump[0].Dest      = offset + 8;
                        sound.Jump[0].HookId    = 0;
                        sound.Jump[0].FadeDelay = 0;
                        break;

                    case 7:     // end of loop
                        sound.Jump[0].Offset = offset - 4;
                        sound.NumJumps++;
                        sound.Region[sound.NumRegions].Offset = offset - 4;
                        sound.Region[sound.NumRegions].Length = 0;
                        sound.NumRegions++;
                        break;

                    default:
                        throw new InvalidOperationException(string.Format("Invalid code in VOC file : {0}", code));
//                            quit = true;
//                            break;
                    }
                    offset += len;
                }
            }
            else if (ptr.ToText() == "iMUS")
            {
                string tag;
                int    size   = 0;
                int    posPtr = 16;

                int curIndexRegion = 0;
                int curIndexJump   = 0;
                int curIndexSync   = 0;
                int curIndexMarker = 0;

                sound.NumRegions = 0;
                sound.NumJumps   = 0;
                sound.NumSyncs   = 0;
                sound.NumMarkers = 0;
                CountElements(ptr, posPtr, ref sound.NumRegions, ref sound.NumJumps, ref sound.NumSyncs, ref sound.NumMarkers);
                sound.Region = new Region[sound.NumRegions];
                sound.Jump   = new Jump[sound.NumJumps];
                sound.Sync   = new Sync[sound.NumSyncs];
                sound.Marker = new Marker[sound.NumMarkers];

                do
                {
                    tag     = ptr.ToText(posPtr);
                    posPtr += 4;
                    switch (tag)
                    {
                    case "FRMT":
                        posPtr        += 12;
                        sound.Bits     = (byte)ptr.ToUInt32BigEndian(posPtr);
                        posPtr        += 4;
                        sound.Freq     = (ushort)ptr.ToUInt32BigEndian(posPtr);
                        posPtr        += 4;
                        sound.Channels = (byte)ptr.ToUInt32BigEndian(posPtr);
                        posPtr        += 4;
                        break;

                    case "TEXT":
                        if (string.Equals(ptr.ToText(posPtr + 8), "exit"))
                        {
                            sound.Marker[curIndexMarker].Pos = ptr.ToInt32BigEndian(posPtr + 4);
                            sound.Marker[curIndexMarker].Ptr = ptr.GetText(posPtr + 8);
                            curIndexMarker++;
                        }
                        size    = ptr.ToInt32BigEndian(posPtr);
                        posPtr += size + 4;
                        break;

                    case "STOP":
                        size    = ptr.ToInt32BigEndian(posPtr);
                        posPtr += size + 4;
                        break;

                    case "REGN":
                        posPtr += 4;
                        sound.Region[curIndexRegion].Offset = ptr.ToInt32BigEndian(posPtr);
                        posPtr += 4;
                        sound.Region[curIndexRegion].Length = ptr.ToInt32BigEndian(posPtr);
                        posPtr += 4;
                        curIndexRegion++;
                        break;

                    case "JUMP":
                        posPtr += 4;
                        sound.Jump[curIndexJump].Offset = ptr.ToInt32BigEndian(posPtr);
                        posPtr += 4;
                        sound.Jump[curIndexJump].Dest = ptr.ToInt32BigEndian(posPtr);
                        posPtr += 4;
                        sound.Jump[curIndexJump].HookId = (byte)ptr.ToInt32BigEndian(posPtr);
                        posPtr += 4;
                        sound.Jump[curIndexJump].FadeDelay = (short)ptr.ToInt32BigEndian(posPtr);
                        posPtr += 4;
                        curIndexJump++;
                        break;

                    case "SYNC":
                        size    = ptr.ToInt32BigEndian(posPtr);
                        posPtr += 4;
                        sound.Sync[curIndexSync].Ptr = new byte[size];
                        Array.Copy(ptr, posPtr, sound.Sync[curIndexSync].Ptr, 0, size);
                        curIndexSync++;
                        posPtr += size;
                        break;

                    case "DATA":
                        posPtr += 4;
                        break;

                    default:
                        throw new InvalidOperationException(
                                  string.Format("ImuseDigiSndMgr::prepareSound({0}/{1}) Unknown sfx header '{2}'", sound.SoundId, sound.Name, tag));
                    }
                } while (tag != "DATA");
                sound.OffsetData = posPtr;
            }
            else
            {
                throw new InvalidOperationException("ImuseDigiSndMgr::prepareSound(): Unknown sound format");
            }
        }