void SetupMusic() { var selectedDevice = Settings.AudioDevice; var deviceHandle = MidiDriver.DetectDevice(Game.Music, selectedDevice); switch (MidiDriver.GetMusicType(deviceHandle)) { case MusicType.Null: Sound.MusicType = MusicDriverTypes.None; break; case MusicType.PCSpeaker: Sound.MusicType = MusicDriverTypes.PCSpeaker; break; case MusicType.PCjr: Sound.MusicType = MusicDriverTypes.PCjr; break; case MusicType.CMS: Sound.MusicType = MusicDriverTypes.CMS; break; case MusicType.FMTowns: Sound.MusicType = MusicDriverTypes.FMTowns; break; case MusicType.AdLib: Sound.MusicType = MusicDriverTypes.AdLib; break; case MusicType.C64: Sound.MusicType = MusicDriverTypes.C64; break; case MusicType.AppleIIGS: Sound.MusicType = MusicDriverTypes.AppleIIGS; break; default: Sound.MusicType = MusicDriverTypes.Midi; break; } // Init iMuse if (Game.Version >= 7) { // Setup for digital iMuse is performed in another place // HACK: don't know why I have to keep this to work var adlibMidiDriver = (MidiDriver)MidiDriver.CreateMidi(Mixer, MidiDriver.DetectDevice(MusicDriverTypes.AdLib, "adlib")); // Setup for digital iMuse is performed in another place Audio.IMuse.IMuse.Create(null, adlibMidiDriver); } else if (Game.Platform == Platform.Apple2GS && Game.Version == 0) { MusicEngine = new Player_AppleII(this, Mixer); } else if (Game.Platform == Platform.C64 && Game.Version <= 1) { var sid = new SID(); MusicEngine = new Player_SID(this, Mixer, sid); } else if (_game.Platform == Platform.Amiga && Game.Version == 2) { var modPlayer = new Player_MOD(Mixer); MusicEngine = new Player_V2A(this, modPlayer); } else if (Game.Platform == Platform.Amiga && Game.Version == 3) { var modPlayer = new Player_MOD(Mixer); MusicEngine = new Player_V3A(this, modPlayer); } else if (Game.Platform == Platform.Amiga && Game.Version <= 4) { MusicEngine = new Player_V4A(this, Mixer); } else if (Game.Platform == Platform.Macintosh && Game.GameId == GameId.Loom) { MusicEngine = new Player_V3M(this, Mixer); } else if (Game.Platform == Platform.Macintosh && Game.GameId == GameId.Monkey1) { MusicEngine = new Player_V5M(this, Mixer); } else if (Game.GameId == GameId.Maniac && Game.Version == 1) { MusicEngine = new Player_V1(this, Mixer, Sound.MusicType == MusicDriverTypes.PCjr); } else if ((Sound.MusicType == MusicDriverTypes.PCSpeaker || Sound.MusicType == MusicDriverTypes.PCjr) && (Game.Version >= 2 && Game.Version <= 4)) { MusicEngine = new Player_V2(this, Mixer, Sound.MusicType == MusicDriverTypes.PCjr); } else if (Sound.MusicType == MusicDriverTypes.CMS) { MusicEngine = new Player_V2CMS(this, Mixer); } else if (Game.Platform == Platform.FMTowns && (Game.Version == 3 || Game.GameId == GameId.Monkey1)) { MusicEngine = TownsPlayer = new Player_Towns_v1(this, Mixer); if (!TownsPlayer.Init()) { Debug.WriteLine("Failed to initialize FM-Towns audio driver"); } } else if (Game.GameId == GameId.Loom || Game.GameId == GameId.Indy3) { MusicEngine = new Player_AD(this, Mixer); } else { MidiDriver nativeMidiDriver = null; MidiDriver adlibMidiDriver = null; if (Sound.MusicType == MusicDriverTypes.AdLib || Sound.MusicType == MusicDriverTypes.FMTowns) { adlibMidiDriver = (MidiDriver)MidiDriver.CreateMidi(Mixer, MidiDriver.DetectDevice(Sound.MusicType == MusicDriverTypes.FMTowns ? MusicDriverTypes.FMTowns : MusicDriverTypes.AdLib, selectedDevice)); adlibMidiDriver.Property(AdlibMidiDriver.PropertyOldAdLib, (Game.Version < 5) ? 1 : 0); adlibMidiDriver.Property(AdlibMidiDriver.PropertyScummOPL3, (Game.GameId == GameId.SamNMax) ? 1 : 0); } else if (Sound.MusicType == MusicDriverTypes.PCSpeaker) { adlibMidiDriver = new PCSpeakerDriver(Mixer); } IMuse = Audio.IMuse.IMuse.Create(nativeMidiDriver, adlibMidiDriver); if (Game.Platform == Platform.FMTowns) { MusicEngine = TownsPlayer = new Player_Towns_v2(this, Mixer, IMuse, true); if (!TownsPlayer.Init()) { throw new InvalidOperationException("ScummEngine::setupMusic(): Failed to initialize FM-Towns audio driver"); } } else { MusicEngine = IMuse; } if (IMuse != null) { IMuse.AddSysexHandler(0x7D, Game.GameId == GameId.SamNMax ? new SysExFunc(new SamAndMaxSysEx().Do) : new SysExFunc(new ScummSysEx().Do)); IMuse.Property(ImuseProperty.GameId, (uint)Game.GameId); // IMuse.Property(ImuseProperty.NativeMt32, _native_mt32); // if (MidiDriver.GetMusicType(deviceHandle) != MusicType.MT32) // MT-32 Emulation shouldn't be GM/GS initialized // IMuse.Property(ImuseProperty.Gs, _enable_gs); if (Sound.MusicType == MusicDriverTypes.PCSpeaker) { IMuse.Property(ImuseProperty.PcSpeaker, 1); } } } if (MusicEngine != null) { MusicEngine.SetMusicVolume(192); } }
protected virtual void KernelSetFunctions() { var args = GetStackList(30); switch (args[0]) { case 3: // Dummy case break; case 4: GrabCursor(args[1], args[2], args[3], args[4]); break; case 5: FadeOut(args[1]); break; case 6: _fullRedraw = true; RedrawBGAreas(); SetActorRedrawFlags(); ProcessActors(); FadeIn((byte)args[1]); break; // TODO: scumm6: start maniac // case 8: // StartManiac(); // break; case 9: KillAllScriptsExceptCurrent(); break; // TODO:scumm6: NukeFlObjects // case 104: /* samnmax */ // NukeFlObjects(args[2], args[3]); // break; case 107: /* set actor scale */ { var a = Actors[args[1]]; a.SetScale(args[2], -1); } break; case 108: /* create proc_special_palette */ case 109: // Case 108 and 109 share the same function if (args.Length != 6) { throw new InvalidOperationException(string.Format("KernelSetFunctions sub op {0}: expected 6 params but got {1}", args[0], args.Length)); } SetShadowPalette(args[3], args[4], args[5], args[1], args[2], 0, 256); break; case 110: Gdi.ClearMaskBuffer(0); break; case 111: { var a = Actors[args[1]]; var modes = new int[2]; Array.Copy(args, 2, modes, 0, args.Length - 2); a.ShadowMode = (byte)(modes[0] + modes[1]); } break; case 112: /* palette shift? */ SetShadowPalette(args[3], args[4], args[5], args[1], args[2], args[6], args[7]); break; case 114: // Sam & Max film noir mode if (Game.GameId == Scumm.IO.GameId.SamNMax) { // At this point ScummVM will already have set // variable 0x8000 to indicate that the game is // in film noir mode. All we have to do here is // to mark the palette as "dirty", because // updatePalette() will desaturate the colors // as they are uploaded to the backend. // // This actually works better than the original // interpreter, where actors would sometimes // still be drawn in color. SetDirtyColors(0, 255); } else { throw new InvalidOperationException("stub KernelSetFunctions_114()"); } break; case 117: // Sam & Max uses this opcode in script-43, right // before a screensaver is selected. // // Sam & Max uses variable 132 to specify the number of // minutes of inactivity (no mouse movements) before // starting the screensaver, so setting it to 0 will // help in debugging. FreezeScripts(0x80); break; case 119: EnqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 0); break; case 120: SwapPalColors(args[1], args[2]); break; case 122: Variables[VariableSoundResult.Value] = IMuse.DoCommand(args.Length - 1, args.Skip(1).ToArray()); break; case 123: CopyPalColor(args[2], args[1]); break; case 124: _saveSound = args[1] != 0; break; default: throw new NotSupportedException(string.Format("KernelSetFunctions: default case {0} (param count {1})", args[0], args.Length)); } }