public SkyCompact() { using (var stream = OpenCompactStream()) { var cptFile = new BinaryReader(stream); var fileVersion = cptFile.ReadUInt16(); if (fileVersion != 0) { throw new NotSupportedException(string.Format("unknown \"sky.cpt\" version {0}", fileVersion)); } if (SkyCptSize != cptFile.BaseStream.Length) { // TODO: GUI //GUI::MessageDialog dialog(_("The \"sky.cpt\" file has an incorrect size.\nPlease (re)download it from www.scummvm.org"), _("OK"), NULL); //dialog.runModal(); throw new NotSupportedException(string.Format("Incorrect sky.cpt size ({0}, expected: {1})", cptFile.BaseStream.Length, SkyCptSize)); } // set the necessary data structs up... var numDataLists = cptFile.ReadUInt16(); var dataListLen = cptFile.ReadUInt16s(numDataLists); var rawLen = cptFile.ReadUInt32(); var srcLen = cptFile.ReadInt32(); var srcBuf = cptFile.ReadBytes(srcLen * 2); var asciiLen = cptFile.ReadInt32(); _asciiBuf = cptFile.ReadBytes(asciiLen); _compacts = new CompactEntry[numDataLists][]; var srcPos = 0; var asciiPos = 0; // and fill them with the compact data for (var lcnt = 0; lcnt < numDataLists; lcnt++) { _compacts[lcnt] = new CompactEntry[dataListLen[lcnt]]; for (var ecnt = 0; ecnt < dataListLen[lcnt]; ecnt++) { var size = srcBuf.ToUInt16(srcPos); srcPos += 2; if (size == 0) { continue; } var type = (CptTypeId)srcBuf.ToUInt16(srcPos); srcPos += 2; var name = ReadName(ref asciiPos); var raw = new byte[size * 2]; Array.Copy(srcBuf, srcPos, raw, 0, size * 2); _compacts[lcnt][ecnt] = new CompactEntry((lcnt << 12) | ecnt) { Type = type, Name = name, Data = type == CptTypeId.Compact ? (object)new Compact(raw) : raw }; srcPos += size * 2; } } // these compacts don't actually exist but only point to other ones... var numDlincs = cptFile.ReadUInt16(); var dlincBuf = cptFile.ReadUInt16s(numDlincs * 2); for (var i = 0; i < numDlincs; i++) { var dlincId = dlincBuf[i * 2]; var destId = dlincBuf[i * 2 + 1]; var name = ReadName(ref asciiPos); var cDest = _compacts[destId >> 12][destId & 0xFFF]; _compacts[dlincId >> 12][dlincId & 0xFFF] = new CompactEntry(dlincId) { Name = name, Data = cDest != null ? cDest.Data : null }; } // if this is v0.0288, parse this diff data var numDiffs = cptFile.ReadUInt16(); var diffSize = cptFile.ReadUInt16() * 2; var diffBuf = cptFile.ReadBytes(diffSize); if (SystemVars.Instance.GameVersion.Version.Minor == 288) { var diffPos = 0; for (var cnt = 0; cnt < numDiffs; cnt++) { var cptId = diffBuf.ToUInt16(diffPos); diffPos += 2; var offset = diffBuf.ToUInt16(diffPos); diffPos += 2; var len = diffBuf.ToUInt16(diffPos); diffPos += 2; var cpt = FetchCptEntry(cptId); cpt.Patch(diffBuf, diffPos, offset * 2, len * 2); diffPos += len * 2; } System.Diagnostics.Debug.Assert(diffPos == diffSize); } // these are the IDs that have to be saved into savegame files. var numSaveIds = cptFile.ReadUInt16(); SaveIds = cptFile.ReadUInt16s(numSaveIds); _resetDataPos = cptFile.BaseStream.Position; } }
private void ImportOldCompact(CompactEntry cptEntry, BinaryReader reader) { // TODO: ImportOldCompact throw new NotImplementedException(); }
public SkyCompact() { using (var stream = OpenCompactStream()) { var cptFile = new BinaryReader(stream); var fileVersion = cptFile.ReadUInt16(); if (fileVersion != 0) throw new NotSupportedException(string.Format("unknown \"sky.cpt\" version {0}", fileVersion)); if (SkyCptSize != cptFile.BaseStream.Length) { // TODO: GUI //GUI::MessageDialog dialog(_("The \"sky.cpt\" file has an incorrect size.\nPlease (re)download it from www.scummvm.org"), _("OK"), NULL); //dialog.runModal(); throw new NotSupportedException(string.Format("Incorrect sky.cpt size ({0}, expected: {1})", cptFile.BaseStream.Length, SkyCptSize)); } // set the necessary data structs up... var numDataLists = cptFile.ReadUInt16(); var dataListLen = cptFile.ReadUInt16s(numDataLists); var rawLen = cptFile.ReadUInt32(); var srcLen = cptFile.ReadInt32(); var srcBuf = cptFile.ReadBytes(srcLen * 2); var asciiLen = cptFile.ReadInt32(); _asciiBuf = cptFile.ReadBytes(asciiLen); _compacts = new CompactEntry[numDataLists][]; var srcPos = 0; var asciiPos = 0; // and fill them with the compact data for (var lcnt = 0; lcnt < numDataLists; lcnt++) { _compacts[lcnt] = new CompactEntry[dataListLen[lcnt]]; for (var ecnt = 0; ecnt < dataListLen[lcnt]; ecnt++) { var size = srcBuf.ToUInt16(srcPos); srcPos += 2; if (size == 0) continue; var type = (CptTypeId)srcBuf.ToUInt16(srcPos); srcPos += 2; var name = ReadName(ref asciiPos); var raw = new byte[size * 2]; Array.Copy(srcBuf, srcPos, raw, 0, size * 2); _compacts[lcnt][ecnt] = new CompactEntry((lcnt << 12) | ecnt) { Type = type, Name = name, Data = type == CptTypeId.Compact ? (object)new Compact(raw) : raw }; srcPos += size * 2; } } // these compacts don't actually exist but only point to other ones... var numDlincs = cptFile.ReadUInt16(); var dlincBuf = cptFile.ReadUInt16s(numDlincs * 2); for (var i = 0; i < numDlincs; i++) { var dlincId = dlincBuf[i * 2]; var destId = dlincBuf[i * 2 + 1]; var name = ReadName(ref asciiPos); var cDest = _compacts[destId >> 12][destId & 0xFFF]; _compacts[dlincId >> 12][dlincId & 0xFFF] = new CompactEntry(dlincId) { Name = name, Data = cDest != null ? cDest.Data : null }; } // if this is v0.0288, parse this diff data var numDiffs = cptFile.ReadUInt16(); var diffSize = cptFile.ReadUInt16() * 2; var diffBuf = cptFile.ReadBytes(diffSize); if (SystemVars.Instance.GameVersion.Version.Minor == 288) { var diffPos = 0; for (var cnt = 0; cnt < numDiffs; cnt++) { var cptId = diffBuf.ToUInt16(diffPos); diffPos += 2; var offset = diffBuf.ToUInt16(diffPos); diffPos += 2; var len = diffBuf.ToUInt16(diffPos); diffPos += 2; var cpt = FetchCptEntry(cptId); cpt.Patch(diffBuf, diffPos, offset * 2, len * 2); diffPos += len * 2; } System.Diagnostics.Debug.Assert(diffPos == diffSize); } // these are the IDs that have to be saved into savegame files. var numSaveIds = cptFile.ReadUInt16(); SaveIds = cptFile.ReadUInt16s(numSaveIds); _resetDataPos = cptFile.BaseStream.Position; } }