public void stop() { status = VDXStatus.Stopped; //fps = 15; }
public void playVideo() { if (status != VDXStatus.Playing) { parseImage(0); //videoOffsets = new Queue<long>(videoMaster); } status = VDXStatus.Playing; }
/// <summary> /// Initialise VDX playback /// </summary> public void play() { if (status != VDXStatus.Playing) { parseImage(0); //videoOffsets = new Queue<long>(videoMaster); status = VDXStatus.Playing; if (audio != null) audio.Play(); } }
/// <summary> /// Open a vdx based on filestream and rl data /// </summary> /// <param name="stream">Stream pointing to the VDX location</param> /// <param name="rl">RL information including offset and length of the VDX</param> /// <param name="flags">VDX flags relating to playback</param> /// <param name="baseSurface">Base surface to build from</param> public ROQ(BinaryReader stream, Surface surface) { this.file = stream; this.surface = surface; status = VDXStatus.Loading; //surface = baseSurface; parseROQ(); parseAudio(); //parseImage(); //audio.Play(true); }
/// <summary> /// Advance an animation frame /// </summary> private void parseVideo(long? off) { try { if (/*(flags & (Groovie.bitFlags.JustAudio)) != 0 || */!off.HasValue && videoOffsets.Count == 0) { status = VDXStatus.Stopped; fps = 15; return; } long offset; VDXChunkHeader chunk; if (!off.HasValue) { do { offset = videoOffsets.Dequeue(); file.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin); chunk = readChunkHeader(); if (videoOffsets.Count == 0) { status = VDXStatus.Stopped; fps = 15; if (chunk.BlockType != VDXBlockType.Video) { return; } } // Repeat prev frame when needed if (chunk.BlockType == VDXBlockType.Zero)// && chunk.PlayCmd == VDXChunkPlayCmd.RepeatPrevFrame) return; if (chunk.PlayCmd != VDXChunkPlayCmd.Sync2) { //Console.WriteLine("non-Sync2 found!"); //return; } } while (chunk.BlockType != VDXBlockType.Video); } else { offset = off.Value; file.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin); chunk = readChunkHeader(); } System.IO.BinaryReader stream; if (chunk.LengthBits == 0 || chunk.LengthMask == 0) { // Non-compressed stream = file; } else { // Compressed System.IO.MemoryStream tmp; decompress(file, ref chunk, out tmp); stream = new System.IO.BinaryReader(tmp); tmp = null; stream.BaseStream.Seek(0, System.IO.SeekOrigin.Begin); } // Is there a palette mapping? ushort localPalette = stream.ReadUInt16(); #region Alter palette if (localPalette > 0) { // Yes - update palette ushort[] pattern = new ushort[16]; // Read updated indicies for (byte i = 0; i < 16; i++) { pattern[i] = stream.ReadUInt16(); } // Update indicies for (byte i = 0; i < 16; i++) { // No update for this ushort if (pattern[i] == 0) { continue; } long offs = i * 16; for (byte j = 0; j < 16; j++) { // Update index if ((32768 & pattern[i]) > 0) { palette[offs] = (uint)((0xff000000) + (stream.ReadByte() * 65536) + (stream.ReadByte() * 256) + stream.ReadByte()); } offs++; pattern[i] = (ushort)(pattern[i] * 2); } } pattern = null; } #endregion #region Video opcodes ushort x = 0, y = 0; byte col1 = 0, col0 = 0, opcode; long limit = (chunk.LengthBits == 0 ? offset + chunk.DataSize : stream.BaseStream.Length); unsafe { uint* p; while (stream.BaseStream.Position < limit) { opcode = stream.ReadByte(); if (opcode <= 0x5F) { col1 = stream.ReadByte(); col0 = stream.ReadByte(); fillTile(x, y, col1, col0, (ushort)(OpcodeMap[(opcode << 1)] + (OpcodeMap[(opcode << 1) + 1] << 8))); x += 4; } else if (opcode == 0x60) { // Fill the 16 pixels with the 16 param colours for (ushort j = 0; j < 4; j++) { p = (uint*)((byte*)surfacePtr + ((y + j) * surface.Width * 4) + 4 * x); *p = palette[stream.ReadByte()]; p++; *p = palette[stream.ReadByte()]; p++; *p = palette[stream.ReadByte()]; p++; *p = palette[stream.ReadByte()]; } x += 4; } else if (opcode == 0x61) { // Newline x = 0; y += 4; } else if (opcode <= 0x6B) { // Skip forward opcode-0x62 blocks x += (ushort)((opcode - 0x62) * 4); } else if (opcode <= 0x75) { // Fill opcode-0x6B blocks with param colours uint col = palette[stream.ReadByte()]; ushort w = (ushort)((opcode - 0x6B) * 4); for (ushort j = 0; j < 4; j++) { p = (uint*)((byte*)surfacePtr + ((y + j) * surface.Width * 4) + 4 * x); for (ushort i = 0; i < w; i++) { *p = col; p++; } } x += (ushort)((opcode - 0x6B) * 4); } else if (opcode <= 0x7F) { // Fill opcode - 0x75 blocks for (byte i = 0; i < (byte)(opcode - 0x75); i++) { uint col = palette[stream.ReadByte()]; for (ushort j = 0; j < 4; j++) { p = (uint*)((byte*)surfacePtr + ((y + j) * surface.Width * 4) + 4 * x); for (ushort k = 0; k < 4; k++) { *p = col; p++; } } x += 4; } } else // if (opcode > 0x7F) { UInt16 map = (ushort)(opcode + (stream.ReadByte() << 8)); fillTile(x, y, stream.ReadByte(), stream.ReadByte(), map); x += 4; } } } #endregion } catch { stop(); } }
/// <summary> /// Open a vdx based on filestream and rl data /// </summary> /// <param name="stream">Stream pointing to the VDX location</param> /// <param name="rl">RL information including offset and length of the VDX</param> /// <param name="flags">VDX flags relating to playback</param> /// <param name="baseSurface">Base surface to build from</param> public VDX(BinaryReader stream, GJD.RLData rl, Surface baseSurface) { this.file = stream; status = VDXStatus.Loading; surface = baseSurface; parseVDX(rl); parseAudio(); parseImage(); }