public void Load(int id) { string filename, path; var directory = ServiceLocator.FileStorage.GetDirectoryName(_vm.Settings.Game.Path); LoadSubtitles(id); // For the PSX version, we'll try the PlayStation stream files if (SystemVars.Platform == Core.IO.Platform.PSX) { _vm.GraphicsManager.PixelFormat = PixelFormat.Rgb16; // The demo uses the normal file names filename = (SystemVars.IsDemo ? SequenceList[id] : SequenceListPsx[id]) + ".str"; _decoder = new PsxStreamDecoder(_vm.Mixer, CDSpeed.CD2x, _vm.GraphicsManager.PixelFormat); } else { filename = $"{SequenceList[id]}.smk"; _decoder = new SmackerDecoder(_vm.Mixer); } path = ScummHelper.LocatePath(directory, filename); var stream = ServiceLocator.FileStorage.OpenFileRead(path); _decoder.LoadStream(stream); _decoder.Start(); }
private void DecodeBlock(BitStream bits, byte[] block, int offset, int pitch, ushort scale, ushort version, PlaneType plane) { // Version 2 just has signed 10 bits for DC // Version 3 has them huffman coded int[] coefficients = new int[8 * 8]; coefficients[0] = ReadDC(bits, version, plane); ReadAC(bits, coefficients, 1); // Read in the AC // Dequantize float[] dequantData = new float[8 * 8]; DequantizeBlock(coefficients, dequantData, scale); // Perform IDCT float[] idctData = new float[8 * 8]; Idct(dequantData, idctData); // Now output the data for (int y = 0; y < 8; y++) { var dst = offset + pitch * y; // Convert the result to be in the range [0, 255] for (int x = 0; x < 8; x++) { block[dst++] = (byte)(ScummHelper.Clip(idctData[y * 8 + x], -128.0f, 127.0f) + 128); } } }
protected virtual ColorCycle[] ReadCYCL() { var colorCycle = new ColorCycle[16]; for (int i = 0; i < 16; i++) { var delay = ScummHelper.SwapBytes(_reader.ReadUInt16()); var start = _reader.ReadByte(); var end = _reader.ReadByte(); colorCycle[i] = new ColorCycle(); if (delay == 0 || delay == 0x0aaa || start >= end) { continue; } colorCycle[i].Counter = 0; colorCycle[i].Delay = (ushort)(16384 / delay); colorCycle[i].Flags = 2; colorCycle[i].Start = start; colorCycle[i].End = end; } return(colorCycle); }
static void WriteMIDIHeader(byte[] input, string type, int ppqn, int totalSize) { int pos = 0; Array.Copy(System.Text.Encoding.UTF8.GetBytes(type), 0, input, pos, 4); pos += 4; Array.Copy(ScummHelper.GetBytesBigEndian((uint)totalSize), 0, input, pos, 4); pos += 4; Array.Copy(System.Text.Encoding.UTF8.GetBytes("MDhd"), 0, input, pos, 4); pos += 4; Array.Copy(new byte[] { 0, 0, 0, 8 }, 0, input, pos, 4); pos += 4; Array.Copy(new byte[8], 0, input, pos, 8); pos += 8; Array.Copy(System.Text.Encoding.UTF8.GetBytes("MThd"), 0, input, pos, 4); pos += 4; Array.Copy(new byte[] { 0, 0, 0, 6 }, 0, input, pos, 4); pos += 4; Array.Copy(new byte[] { 0, 0, 0, 1 }, 0, input, pos, 4); pos += 4; // MIDI format 0 with 1 track input[pos++] = (byte)(ppqn >> 8); input[pos++] = (byte)(ppqn & 0xFF); Array.Copy(System.Text.Encoding.UTF8.GetBytes("MTrk"), 0, input, pos, 4); pos += 4; Array.Copy(ScummHelper.GetBytesBigEndian((uint)totalSize), 0, input, pos, 4); pos += 4; }
TrsFile GetStrings(ScummEngine vm, string file, bool isEncoded) { // Debug.WriteLine("trying to read text resources from {0}", file); var filename = ScummHelper.LocatePath(ServiceLocator.FileStorage.GetDirectoryName(_vm.Game.Path), ServiceLocator.FileStorage.GetFileName(file)); return(filename != null?isEncoded?TrsFile.LoadEncoded(filename) : TrsFile.Load(filename) : null); }
TimeSpan GetTimeToWaitBeforeLoop(TimeSpan lastTimeLoop) { var numTicks = ScummHelper.ToTicks(timeToWait); // Notify the script about how much time has passed, in ticks (60 ticks per second) if (VariableTimer.HasValue) { _variables[VariableTimer.Value] = numTicks; } if (VariableTimerTotal.HasValue) { _variables[VariableTimerTotal.Value] += numTicks; } // Determine how long to wait before the next loop iteration should start deltaTicks = VariableTimerNext.HasValue ? _variables[VariableTimerNext.Value] : 4; if (deltaTicks < 1) // Ensure we don't get into an endless loop { deltaTicks = 1; // by not decreasing sleepers. } timeToWait = ScummHelper.ToTimeSpan(deltaTicks); if (timeToWait > lastTimeLoop) { timeToWait -= lastTimeLoop; } else { timeToWait = TimeSpan.Zero; } return(timeToWait); }
public void SeekSan(string filename, int pos, int contFrame) { _seekFile = ScummHelper.LocatePath(ServiceLocator.FileStorage.GetDirectoryName(_vm.Game.Path), ServiceLocator.FileStorage.GetFileName(filename)); _seekPos = pos; _seekFrame = contFrame; _pauseTime = 0; }
protected override bool HandleSubTags(ref int offset) { if (_tbufferSize - offset >= 8) { var type = System.Text.Encoding.UTF8.GetString(_tbuffer, offset, 4); var size = ScummHelper.SwapBytes(BitConverter.ToUInt32(_tbuffer, offset + 4)); var available_size = _tbufferSize - offset; switch (type) { case "MAP ": _inData = false; if (available_size >= (size + 8)) { var tmp = new byte[_tbuffer.Length - offset]; Array.Copy(_tbuffer, offset, tmp, 0, tmp.Length); HandleMap(tmp); } break; case "DATA": _inData = true; _dataSize = (int)size; offset += 8; { int reqsize = 1; if (_channels == 2) { reqsize *= 2; } if (_bitsize == 16) { reqsize *= 2; } else if (_bitsize == 12) { if (reqsize > 1) { reqsize = reqsize * 3 / 2; } else { reqsize = 3; } } if ((size % reqsize) != 0) { Debug.WriteLine("Invalid iMUS sound data size : ({0} %% {1}) != 0, correcting...", size, reqsize); size += (uint)(3 - (size % reqsize)); } } return(false); // default: // Console.Error.WriteLine("unknown Chunk in iMUS track : {0} ", type); // break; } offset += (int)(size + 8); return(true); } return(false); }
public bool Exists(string fileName) { // Try the file name by itself var path = ScummHelper.LocatePath(_gamePath, fileName); if (path != null) { return(true); } // Try the .rsrc extension // if (File::exists(fileName + ".rsrc")) // return true; // Check if we have a MacBinary file path = ScummHelper.LocatePath(_gamePath, fileName + ".bin"); if (path != null /*&& isMacBinary(tempFile)*/) { return(true); } // Check if we have an AppleDouble file // if (tempFile.open(constructAppleDoubleName(fileName)) && tempFile.readUint32BE() == 0x00051607) // return true; return(false); }
private void LoadSubtitles(int id) { if (SystemVars.ShowText != 0) { var filename = $"{SequenceList[id]}.txt"; var path = ScummHelper.LocatePath(_directory, filename); if (path != null) { using (var f = new StreamReader(ServiceLocator.FileStorage.OpenFileRead(path))) { string line; while ((line = f.ReadLine()) != null) { var m = _regex.Match(line); if (m.Success) { var start = ushort.Parse(m.Groups[1].Value); var end = ushort.Parse(m.Groups[2].Value); var color = ushort.Parse(m.Groups[3].Value); var text = m.Groups[4].Value; _movieTexts.Add(new MovieText(start, end, text, color)); } } } } } }
public Stream OpenContent(string path) { var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation; var fullPath = ScummHelper.LocatePath(installedLocation.Path, path); return(OpenFileRead(fullPath)); }
public override void SetDirection(int direction) { int dir = ScummHelper.NewDirToOldDir(direction); int res = 0; switch (dir) { case 0: res = 4; // Left break; case 1: res = 5; // Right break; case 2: res = 6; // Face Camera break; default: res = 7; // Face Away break; } AnimFrameRepeat = -1; AnimateActor(res); }
public bool Open(string filename, ref bool compressed) { if (_file != null) { return(true); } filename = ScummHelper.LocatePath(ServiceLocator.FileStorage.GetDirectoryName(ScummEngine.Instance.Game.Path), filename); _file = new BinaryReader(ServiceLocator.FileStorage.OpenFileRead(filename)); int slot = _cache.MatchFile(filename); Debug.Assert(slot != -1); compressed = _cache.IsSndDataExtComp(slot); _numFiles = _cache.GetNumFiles(slot); Debug.Assert(_numFiles != 0); _bundleTable = _cache.GetTable(slot); _indexTable = _cache.GetIndexTable(slot); Debug.Assert(_bundleTable != null); _compTableLoaded = false; _outputSize = 0; _lastBlock = -1; return(true); }
public NutRenderer(ScummEngine vm, string filename) { _vm = vm; var directory = ServiceLocator.FileStorage.GetDirectoryName(_vm.Game.Path); var path = ScummHelper.LocatePath(directory, filename); LoadFont(path); }
public void SetFacing(Actor a) { _mirror = (ScummHelper.NewDirToOldDir(a.Facing) != 0) || ((akhd.flags & 1) != 0); if (a.Flip) { _mirror = !_mirror; } }
public Stream OpenContent(string path) { var exe = Environment.GetCommandLineArgs()[0]; var dir = Path.GetDirectoryName(exe); var fullPath = ScummHelper.LocatePath(dir, path); return(OpenFileRead(fullPath)); }
void SetupSfxFile() { var dir = ServiceLocator.FileStorage.GetDirectoryName(vm.Game.Path); _sfxFilename = (from filename in new[] { vm.Game.Id + ".sou", "monster.sou" } let path = ScummHelper.NormalizePath(ServiceLocator.FileStorage.Combine(dir, filename)) where path != null select path).FirstOrDefault(); }
byte ApplyVolumeAdjust(byte @in) { int @out = _tLevel[_musicData[_musicPos + 1]]; @out += (@in & 0x7f); @out = ScummHelper.Clip(@out, 1, 127); return((byte)(@out & 0xff)); }
static int GenerateSine(int x, int oscLength) { if (oscLength == 0) { return(0); } // TODO: Maybe using a look-up-table would be better? return(ScummHelper.Clip((int)(128 * Math.Sin(2.0 * Math.PI * x / oscLength)), -128, 127)); }
protected override ResourceFile OpenRoom(byte roomIndex) { var diskNum = Index.RoomResources[roomIndex].RoomNum; var diskName = string.Format(Game.Pattern, diskNum); var game1Path = ScummHelper.NormalizePath(ServiceLocator.FileStorage.Combine(Directory, diskName)); var file = new ResourceFile5(new XorStream(ServiceLocator.FileStorage.OpenFileRead(game1Path), 0x69)); return(file); }
private BinaryReader TryToOpen(string filename) { var directory = ServiceLocator.FileStorage.GetDirectoryName(_settings.Game.Path); var path = ScummHelper.LocatePath(directory, filename); if (path != null) { return(new BinaryReader(ServiceLocator.FileStorage.OpenFileRead(path))); } return(null); }
protected override void WriteVariable(uint index, int value) { // Console.WriteLine("SetResult({0},{1})", index, value); if ((index & 0xF000) == 0) { ScummHelper.AssertRange(0, index, _resManager.NumVariables - 1, "variable (writing)"); Variables[index] = value; return; } if ((index & 0x8000) != 0) { if (Game.Version <= 3 && !(Game.GameId == GameId.Indy3 && Game.Platform == Platform.FMTowns) && !(Game.GameId == GameId.Loom && Game.Platform == Platform.PCEngine)) { var bit = (int)(index & 0xF); index = (index >> 4) & 0xFF; ScummHelper.AssertRange(0, index, _resManager.NumVariables - 1, "variable (writing)"); if (value > 0) { Variables[index] |= (1 << bit); } else { Variables[index] &= ~(1 << bit); } } else { index &= 0x7FFF; ScummHelper.AssertRange(0, index, _bitVars.Length - 1, "bit variable (writing)"); _bitVars[(int)index] = value != 0; } return; } if ((index & 0x4000) != 0) { if (Game.Features.HasFlag(GameFeatures.FewLocals)) { index &= 0xF; } else { index &= 0xFFF; } ScummHelper.AssertRange(0, index, 20, "local variable (writing)"); //Console.WriteLine ("SetLocalVariables(script={0},var={1},value={2})", CurrentScript, index, value); Slots[CurrentScript].LocalVariables[index] = value; return; } }
protected override ResourceFile OpenRoom(byte roomIndex) { var diskNum = Index.RoomResources[roomIndex].RoomNum; var diskName = Game.Pattern == null?string.Format("{0}.{1:000}", Game.Id, diskNum) : string.Format(Game.Pattern, diskNum); var game1Path = ScummHelper.NormalizePath(ServiceLocator.FileStorage.Combine(Directory, diskName)); var file = new ResourceFile7(ServiceLocator.FileStorage.OpenFileRead(game1Path)); return(file); }
protected override byte[] ReadCharset(byte id) { var diskName = string.Format("{0:00}.lfl", 99 - id); var path = ScummHelper.NormalizePath(ServiceLocator.FileStorage.Combine(Directory, diskName)); using (var file = ServiceLocator.FileStorage.OpenFileRead(path)) { var reader = new BinaryReader(file); var size = reader.ReadUInt16(); return(reader.ReadBytes(size)); } }
void AdvanceInput(RhtChannel ins) { sbyte cur = (sbyte)ins.data[ins.posOffset++]; for (int i = 0; i < 2; i++) { int b = (2 * (cur & 7) + 1) * stepTable[ins.decState] / 8; ins.samples[i] = (short)ScummHelper.Clip(ins.samples[i ^ 1] + ((cur & 8) != 0 ? b : -b), -2048, 2047); ins.decState = (sbyte)ScummHelper.Clip(ins.decState + adjustIndex[cur & 7], 0, 48); cur >>= 4; } }
static void akos_queCommand(byte cmd, Actor a, int param_1, int param_2, ScummEngine vm) { var v = (ScummEngine6)vm; v._akosQueuePos++; ScummHelper.AssertRange(0, v._akosQueuePos, 31, "akos_queCommand: _akosQueuePos"); v._akosQueue[v._akosQueuePos].cmd = cmd; v._akosQueue[v._akosQueuePos].actor = a.Number; v._akosQueue[v._akosQueuePos].param1 = (short)param_1; v._akosQueue[v._akosQueuePos].param2 = (short)param_2; }
protected virtual bool DrawStrip(PixelNavigator navDst, int width, int height, int stripnr, BinaryReader smapReader) { // Do some input verification and make sure the strip/strip offset // are actually valid. Normally, this should never be a problem, // but if e.g. a savegame gets corrupted, we can easily get into // trouble here. See also bug #795214. long offset = -1; long smapLen; if (game.Features.HasFlag(GameFeatures.SixteenColors)) { smapLen = smapReader.ReadInt16(); if (stripnr * 2 + 2 < smapLen) { smapReader.BaseStream.Seek(stripnr * 2, SeekOrigin.Current); offset = smapReader.ReadInt16(); } } else if (game.Version < 5) { smapLen = smapReader.ReadInt32(); if (stripnr * 4 + 4 < smapLen) { smapReader.BaseStream.Seek(stripnr * 4, SeekOrigin.Current); offset = smapReader.ReadInt32(); } } else if (game.Version == 8) { smapLen = smapReader.BaseStream.Length; // Skip to the BSTR->WRAP->OFFS chunk smapReader.BaseStream.Seek(24, SeekOrigin.Current); if (stripnr * 4 + 8 < smapLen) { smapReader.BaseStream.Seek(stripnr * 4, SeekOrigin.Current); offset = 16 + smapReader.ReadUInt32(); } } else { smapLen = smapReader.BaseStream.Length; if (stripnr * 4 + 8 < smapLen) { smapReader.BaseStream.Seek(stripnr * 4, SeekOrigin.Begin); offset = smapReader.ReadUInt32() - 8; } } ScummHelper.AssertRange(0, offset, smapLen - 1, "screen strip"); smapReader.BaseStream.Seek(offset, SeekOrigin.Begin); return(DecompressBitmap(navDst, smapReader, height)); }
public void Play(int track, int numLoops, int startFrame, int duration, bool only_emulate) { if (numLoops != 0 || startFrame != 0) { _cd.track = track; _cd.numLoops = numLoops; _cd.start = startFrame; _cd.duration = duration; // Try to load the track from a compressed data file, and if found, use // that. If not found, attempt to start regular Audio CD playback of // the requested track. string[] trackName = new string[2]; trackName[0] = string.Format("track{0}", track); trackName[1] = string.Format("track{0:00}", track); ISeekableAudioStream stream = null; var directory = ServiceLocator.FileStorage.GetDirectoryName(_vm.Game.Path); for (int i = 0; stream == null && i < 2; ++i) { var path = ScummHelper.LocatePath(directory, trackName[i]); if (path != null) { // TODO: open stream } } // Stop any currently playing emulated track _mixer.StopHandle(_handle); if (stream != null) { var start = new Timestamp(0, startFrame, 75); var end = duration != 0 ? new Timestamp(0, startFrame + duration, 75) : stream.Length; /* * FIXME: Seems numLoops == 0 and numLoops == 1 both indicate a single repetition, * while all other positive numbers indicate precisely the number of desired * repetitions. Finally, -1 means infinitely many */ _emulating = true; _handle = _mixer.PlayStream(SoundType.Music, LoopingAudioStream.Create(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance); } else { _emulating = false; if (!only_emulate) { PlayCD(track, numLoops, startFrame, duration); } } } }
public bool PlayPsx(ushort id, bool loop) { Stop(); string path; if (_file == null) { path = ScummHelper.LocatePath(_directory, "tunes.dat"); if (path == null) { return(false); } _file = ServiceLocator.FileStorage.OpenFileRead(path); } path = ScummHelper.LocatePath(_directory, "tunes.tab"); if (path == null) { return(false); } uint offset; int size; using (var tableFile = ServiceLocator.FileStorage.OpenFileRead(path)) { var br = new BinaryReader(tableFile); tableFile.Seek((id - 1) * 8, SeekOrigin.Begin); offset = br.ReadUInt32() * 0x800; size = br.ReadInt32(); } // Because of broken tunes.dat/tab in psx demo, also check that tune offset is // not over file size if ((size != 0) && (size != int.MaxValue) && ((int)(offset + size) <= _file.Length)) { _file.Seek(offset, SeekOrigin.Begin); var br = new BinaryReader(_file); var ms = new MemoryStream(br.ReadBytes(size)); _audioSource = new LoopingAudioStream(new XAStream(ms, 11025), loop ? 0 : 1); FadeUp(); } else { _audioSource = null; return(false); } return(true); }
void StartSoundEx(int sound, int velo, int pan, int note) { var ptr = _vm.ResourceManager.GetSound(_vm.Sound.MusicType, sound); var offset = 2; if (pan > 99) { pan = 99; } velo = velo != 0 ? (velo * ptr[offset + 14] + 50) / 100 : ptr[offset + 14]; velo = ScummHelper.Clip(velo, 1, 255); ushort pri = ptr.ToUInt16(offset + 10); if (ptr[offset + 13] == 0) { velo >>= 1; if (velo == 0) { velo = 1; } pan = pan != 0 ? (((pan << 7) - pan) + 50) / 100 : 64; PlayPcmTrack(sound, ptr, offset + 6, velo != 0 ? velo : ptr[offset + 14] >> 1, pan, note != 0 ? note : ptr[offset + 50], pri); } else if (ptr[offset + 13] == 2) { int volLeft = velo; int volRight = velo; if (pan < 50) { volRight = ((pan * 2 + 1) * velo + 50) / 100; } else if (pan > 50) { volLeft = (((99 - pan) * 2 + 1) * velo + 50) / 100; } SetVolumeCD(volLeft, volRight); if (_cdaForceRestart == 0 && sound == _cdaCurrentSound) { return; } PlayCdaTrack(sound, ptr, offset + 6, true); } }