NScumm.Scumm.Audio.IMuse.IMuseInternal.DoCommandInternal C# (CSharp) Method

DoCommandInternal() protected method

protected DoCommandInternal ( int numargs, int a ) : int
numargs int
a int
return int
        protected int DoCommandInternal(int numargs, int[] a)
        {
            if (numargs < 1)
                return -1;

            int i;
            byte cmd = (byte)(a[0] & 0xFF);
            byte param = (byte)(a[0] >> 8);
            Player player = null;

            if (!_initialized && (cmd != 0 || param != 0))
                return -1;

//            {
//                var str = string.Format("DoCommand - {0} ({1}/{2})", a[0], (int)param, (int)cmd);
//                for (i = 1; i < numargs; ++i)
//                    str += string.Format(", {0}", a[i]);
//                Debug.WriteLine(str);
//            }

            if (param == 0)
            {
                switch (cmd)
                {
                    case 6:
                        if (a[1] > 127)
                            return -1;
                        else
                        {
                            Debug.WriteLine("IMuse DoCommand(6) - SetImuseMasterVolume ({0})", a[1]);
                            return SetImuseMasterVolume((uint)((a[1] << 1) | (a[1] != 0 ? 0 : 1))); // Convert from 0-127 to 0-255
                        }
                    case 7:
                        Debug.WriteLine("IMuse DoCommand(7) - GetMasterVolume ({0})", a[1]);
                        return _master_volume / 2; // Convert from 0-255 to 0-127
                    case 8:
                        return StartSoundInternal(a[1]) ? 0 : -1;
                    case 9:
                        return StopSoundInternal(a[1]);
                    case 10: // FIXME: Sam and Max - Not sure if this is correct
                        return StopAllSoundsInternal();
                    case 11:
                        return StopAllSoundsInternal();
                    case 12:
                            // Sam & Max: Player-scope commands
                        player = FindActivePlayer(a[1]);
                        if (player == null)
                            return -1;

                        switch (a[3])
                        {
                            case 6:
                                    // Set player volume.
                                return player.SetVolume((byte)a[4]);
                            default:
//                                Console.Error.WriteLine("IMuseInternal::DoCommand(12) unsupported sub-command {0}", a[3]);
                                break;
                        }
                        return -1;
                    case 13:
                        return GetSoundStatusInternal(a[1], true);
                    case 14:
                            // Sam and Max: Parameter fade
                        player = FindActivePlayer(a[1]);
                        if (player != null)
                            return player.AddParameterFader((ParameterFaderType)a[3], a[4], a[5]);
                        return -1;

                    case 15:
                            // Sam & Max: Set hook for a "maybe" jump
                        player = FindActivePlayer(a[1]);
                        if (player != null)
                        {
                            player.SetHook(0, (byte)a[3], 0);
                            return 0;
                        }
                        return -1;
                    case 16:
                        Debug.WriteLine("IMuse DoCommand(16) - SetVolChan ({0}, {1})", a[1], a[2]);
                        return SetVolchan(a[1], a[2]);
                    case 17:
                        if (_game_id != GameId.SamNMax)
                        {
                            Debug.WriteLine("IMuse DoCommand(17) - setChannelVolume ({0}, {1})", a[1], a[2]);
                            return SetChannelVolume((uint)a[1], (uint)a[2]);
                        }
                        else
                        {
                            if (a[4] != 0)
                            {
                                int[] b = new int[16];
                                for (i = 0; i < numargs; ++i)
                                    b[i] = a[i];
                                return ImSetTrigger(b[1], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11]);
                            }
                            else
                            {
                                return ImClearTrigger(a[1], a[3]);
                            }
                        }
                    case 18:
                        if (_game_id != GameId.SamNMax)
                        {
                            return SetVolchanEntry(a[1], (uint)a[2]);
                        }
                        else
                        {
                            // Sam & Max: ImCheckTrigger.
                            // According to Mike's notes to Ender,
                            // this function returns the number of triggers
                            // associated with a particular player ID and
                            // trigger ID.
                            a[0] = 0;
                            for (i = 0; i < _snm_triggers.Length; ++i)
                            {
                                if (_snm_triggers[i].Sound == a[1] && _snm_triggers[i].Id != 0 &&
                                    (a[3] == -1 || _snm_triggers[i].Id == a[3]))
                                {
                                    ++a[0];
                                }
                            }
                            return a[0];
                        }
                    case 19:
                            // Sam & Max: ImClearTrigger
                            // This should clear a trigger that's been set up
                            // with ImSetTrigger(cmd == 17). Seems to work....
                        return ImClearTrigger(a[1], a[3]);
                    case 20:
                            // Sam & Max: Deferred Command
                        AddDeferredCommand(a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
                        return 0;
                    case 2:
                    case 3:
                        return 0;
                    default:
//                        Console.Error.WriteLine("DoCommand({0} [{1}/{2}], {3}, {4}, {5}, {6}, {7}, {8}, {9}) unsupported", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
                        break;
                }
            }
            else if (param == 1)
            {
                if (((1 << cmd) & 0x783FFF) != 0)
                {
                    player = FindActivePlayer(a[1]);
                    if (player == null)
                        return -1;
                    if (((1 << cmd) & (1 << 11 | 1 << 22)) != 0)
                    {
                        Contract.Assert(a[2] >= 0 && a[2] <= 15);
                        // TODO: vs: check if it's correct...
                        player = player.GetPart((byte)a[2]).Player;
                        if (player == null)
                            return -1;
                    }
                }

                switch (cmd)
                {
                    case 0:
                        if (_game_id == GameId.SamNMax)
                        {
                            if (a[3] == 1) // Measure number
                                        return (int)(((player.GetBeatIndex() - 1) >> 2) + 1);
                            else if (a[3] == 2) // Beat number
                                        return (int)player.GetBeatIndex();
                            return -1;
                        }
                        else
                        {
                            return player.GetParam(a[2], (byte)a[3]);
                        }
                    case 1:
                        if (_game_id == GameId.SamNMax)
                        {
                            // FIXME: Could someone verify this?
                            //
                            // This jump instruction is known to be used in
                            // the following cases:
                            //
                            // 1) Going anywhere on the USA map
                            // 2) Winning the Wak-A-Rat game
                            // 3) Losing or quitting the Wak-A-Rat game
                            // 4) Conroy hitting Max with a golf club
                            //
                            // For all these cases the position parameters
                            // are always the same: 2, 1, 0, 0.
                            //
                            // 5) When leaving the bigfoot party. The
                            //    position parameters are: 3, 4, 300, 0
                            // 6) At Frog Rock, when the UFO appears. The
                            //    position parameters are: 10, 4, 400, 1
                            //
                            // The last two cases used to be buggy, so I
                            // have made a change to how the last two
                            // position parameters are handled. I still do
                            // not know if it's correct, but it sounds
                            // good to me at least.

                            Debug.WriteLine("DoCommand({0} [{1}/{2}], {3}, {4}, {5}, {6}, {7}, {8}, {9})", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
                            player.Jump((uint)(a[3] - 1), (uint)((a[4] - 1) * 4 + a[5]), (uint)(a[6] + ((a[7] * player.GetTicksPerBeat()) >> 2)));
                        }
                        else
                            player.SetPriority(a[2]);
                        return 0;
                    case 2:
                        return player.SetVolume((byte)a[2]);
                    case 3:
                        player.SetPan(a[2]);
                        return 0;
                    case 4:
                        return player.SetTranspose((byte)a[2], a[3]);
                    case 5:
                        player.SetDetune(a[2]);
                        return 0;
                    case 6:
                            // WORKAROUND for bug #1324106. When playing the
                            // "flourishes" as Rapp's body appears from his ashes,
                            // MI2 sets up triggers to pause the music, in case the
                            // animation plays too slowly, and then the music is
                            // manually unpaused for the next part of the music.
                            //
                            // In ScummVM, the animation finishes slightly too
                            // quickly, and the pause command is run *after* the
                            // unpause command. So we work around it by ignoring
                            // all attempts at pausing this particular sound.
                            //
                            // I could have sworn this wasn't needed after the
                            // recent timer change, but now it looks like it's
                            // still needed after all.
                        if (_game_id != GameId.Monkey2 || player.Id != 183 || a[2] != 0)
                        {
                            player.SetSpeed((byte)a[2]);
                        }
                        return 0;
                    case 7:
                        return player.Jump((uint)a[2], (uint)a[3], (uint)a[4]) ? 0 : -1;
                    case 8:
                        return player.Scan((uint)a[2], (uint)a[3], (uint)a[4]);
                    case 9:
                        return player.SetLoop((uint)a[2], (uint)a[3], (uint)a[4], (uint)a[5], (uint)a[6]) ? 0 : -1;
                    case 10:
                        player.ClearLoop();
                        return 0;
                    case 11:
                            // TODO: vs: check if it's correct...
                        player.Part.SetOnOff(a[3] != 0);
                        return 0;
                    case 12:
                        return player.SetHook((byte)a[2], (byte)a[3], (byte)a[4]);
                    case 13:
                        return player.AddParameterFader(ParameterFaderType.Volume, a[2], a[3]);
                    case 14:
                        return EnqueueTrigger(a[1], a[2]);
                    case 15:
                        return EnqueueCommand(a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
                    case 16:
                        return ClearQueue();
                    case 19:
                        return player.GetParam(a[2], (byte)a[3]);
                    case 20:
                        return player.SetHook((byte)a[2], (byte)a[3], (byte)a[4]);
                    case 21:
                        return -1;
                    case 22:
                            // TODO: vs: check if it's correct
                        player.Part.Volume = a[3];
                        return 0;
                    case 23:
                        return QueryQueue(a[1]);
                    case 24:
                        return 0;
                    default:
//                        Console.Error.WriteLine("DoCommand({0} [{1}/{2}], {3}, {4}, {5}, {6}, {7}, {8}, {9}) unsupported", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
                        return -1;
                }
            }

            return -1;
        }
    

Same methods

IMuseInternal::DoCommandInternal ( int a, int b, int c, int d, int e, int f, int g, int h ) : int