/// <summary> /// Reads a FWAV chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a FWAV chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { Name = io.ReadNullTerminatedString(); } }
private void OKButton_Click(object sender, EventArgs e) { var name = Path.Combine(FSOEnvironment.ContentDir, "Objects/" +NameEntry.Text+".iff"); var objProvider = Content.Content.Get().WorldObjects; if (NameEntry.Text == "") { MessageBox.Show("Name cannot be empty!", "Invalid IFF Name"); } else { //search for duplicates. lock (objProvider.Entries) { foreach (var obj in objProvider.Entries.Values) { if (obj.FileName == name) { MessageBox.Show("Name "+name+" already taken!", "Invalid IFF Name"); return; } } } //we're good. Create the IFF and add it. Don't drop the lock, so changes cannot be made between this check. var iff = new IffFile(); iff.RuntimeInfo.Path = name; iff.RuntimeInfo.State = IffRuntimeState.Standalone; iff.Filename = NameEntry.Text; DialogResult = DialogResult.OK; InitIff = iff; Close(); } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt16(1); io.WriteVariableLengthPascalString(SourceIff); io.WriteUInt16((ushort)Entries.Length); foreach (var ent in Entries) { io.WriteCString(ent.Type, 4); io.WriteUInt16(ent.ChunkID); io.WriteByte((byte)(ent.Delete ? 1 : 0)); if (!ent.Delete) { io.WriteVariableLengthPascalString(ent.ChunkLabel); //0 length means no replacement io.WriteUInt16(ent.ChunkFlags); io.WriteUInt16(ent.NewChunkID); io.WriteUInt32(ent.NewDataSize); io.WriteUInt32((uint)ent.Patches.Length); uint lastOff = 0; foreach (var p in ent.Patches) { io.WriteVarLen(p.Offset-lastOff); lastOff = p.Offset; io.WriteVarLen(p.Size); io.WriteByte((byte)p.Mode); if (p.Mode == PIFFPatchMode.Add) io.WriteBytes(p.Data); } } } } return true; }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteNullTerminatedString(Name); } return true; }
public void DiscardChange(IffFile file) { lock (this) { UnregisterObjects(file); file.Revert(); ChangedFiles.Remove(file); RegisterObjects(file); } }
public void LoadCharacters(bool clearLast) { var objs = (TS1ObjectProvider)ContentManager.WorldObjects; if (objs.Entries == null) { return; } if (clearLast) { foreach (var obj in objs.Entries.Where(x => x.Value.Source == GameObjectSource.User)) { objs.RemoveObject((uint)obj.Key); } } NextSim = 0; var path = Path.Combine(UserPath, "Characters/"); var files = Directory.EnumerateFiles(path); foreach (var filename in files) { if (Path.GetExtension(filename) != ".iff") { return; } int userID; var name = Path.GetFileName(filename); if (name.Length > 8 && int.TryParse(name.Substring(4, 5), out userID) && userID >= NextSim) { NextSim = userID + 1; } var file = new IffFile(filename); file.MarkThrowaway(); var objects = file.List <OBJD>(); if (objects != null) { foreach (var obj in objects) { objs.Entries[obj.GUID] = new GameObjectReference(objs) { FileName = filename, ID = obj.GUID, Name = obj.ChunkLabel, Source = GameObjectSource.User, Group = (short)obj.MasterID, SubIndex = obj.SubIndex }; } } } }
public override bool Execute(VM vm) { //the client should ignore these. Can be sent before state sync when joining job lots (by accident) if (!vm.BlueprintRestore) { return(true); } vm.SetGlobalValue(11, JobLevel); //set job level beforehand if (IffData) { var iff = new IffFile(); using (var stream = new MemoryStream(XMLData)) { iff.Read(stream); } var fsov = iff.List <FSOV>()?.FirstOrDefault(); if (fsov != null) { var marshal = new VMMarshal(); using (var read = new BinaryReader(new MemoryStream(fsov.Data))) marshal.Deserialize(read); vm.Load(marshal); } else { var activator = new VMTS1Activator(vm, vm.Context.World, JobLevel); var blueprint = activator.LoadFromIff(iff); } vm.TS1State.VerifyFamily(vm); } else { XmlHouseData lotInfo; using (var stream = new MemoryStream(XMLData)) { lotInfo = XmlHouseData.Parse(stream); } var activator = new VMWorldActivator(vm, vm.Context.World); activator.FloorClip = new Microsoft.Xna.Framework.Rectangle(FloorClipX, FloorClipY, FloorClipWidth, FloorClipHeight); activator.Offset = new Microsoft.Xna.Framework.Point(OffsetX, OffsetY); activator.TargetSize = TargetSize; var blueprint = activator.LoadFromXML(lotInfo); } /*if (VM.UseWorld) * { * vm.Context.World.InitBlueprint(blueprint); * vm.Context.Blueprint = blueprint; * }*/ return(true); }
public int AddYOff; //accounts for difference between roofed and unroofed. relative to the base. public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { Width = io.ReadInt32(); Height = io.ReadInt32(); BaseYOff = io.ReadInt32(); XOff = io.ReadInt32(); //0 in all cases i've found, pretty much? AddYOff = io.ReadInt32(); } }
public void InitTS1() { var floorGlobalsPath = Path.Combine(ContentManager.TS1BasePath, "GameData/floors.iff"); var floorGlobals = new IffFile(floorGlobalsPath); FloorGlobals = floorGlobals; var buildGlobalsPath = Path.Combine(ContentManager.TS1BasePath, "GameData/Build.iff"); BuildGlobals = new IffFile(buildGlobalsPath); //todo: centralize? InitGlobals(); //load *.flr iffs from both the TS1 provider and folder ushort floorID = 256; var files = new FileProvider <IffFile>(ContentManager, new IffCodec(), new Regex(".*/Floors.*\\.flr")); files.UseTS1 = true; var ts1 = new TS1SubProvider <IffFile>(ContentManager.TS1Global, ".flr"); files.Init(); ts1.Init(); var compo = new CompositeProvider <IffFile>(new List <IContentProvider <IffFile> >() { ts1, files }); Floors = compo; var all = compo.ListGeneric(); foreach (var entry in all) { var iff = (IffFile)entry.GetThrowawayGeneric(); DynamicFloorFromID[Path.GetFileNameWithoutExtension(entry.ToString().Replace('\\', '/')).ToLowerInvariant()] = floorID; var catStrings = iff.Get <STR>(0); Entries.Add(floorID, new FloorReference(this) { ID = floorID, FileName = Path.GetFileName(entry.ToString().Replace('\\', '/')).ToLowerInvariant(), Name = catStrings.GetString(0), Price = int.Parse(catStrings.GetString(1)), Description = catStrings.GetString(2) }); floorID++; } NumFloors = floorID; }
public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { Version = io.ReadUInt16(); SourceIff = io.ReadVariableLengthPascalString(); Entries = new PIFFEntry[io.ReadUInt16()]; for (int i = 0; i < Entries.Length; i++) { var e = new PIFFEntry(); e.Type = io.ReadCString(4); e.ChunkID = io.ReadUInt16(); e.Delete = io.ReadByte() > 0; if (!e.Delete) { e.ChunkLabel = io.ReadVariableLengthPascalString(); e.ChunkFlags = io.ReadUInt16(); if (Version > 0) { e.NewChunkID = io.ReadUInt16(); } else { e.NewChunkID = e.ChunkID; } e.NewDataSize = io.ReadUInt32(); var size = io.ReadUInt32(); e.Patches = new PIFFPatch[size]; uint lastOff = 0; for (int j = 0; j < e.Patches.Length; j++) { var p = new PIFFPatch(); p.Offset = lastOff + io.ReadVarLen(); lastOff = p.Offset; p.Size = io.ReadVarLen(); p.Mode = (PIFFPatchMode)io.ReadByte(); if (p.Mode == PIFFPatchMode.Add) { p.Data = io.ReadBytes(p.Size); } e.Patches[j] = p; } } Entries[i] = e; } } }
public override bool Write(IffFile iff, Stream stream) { if (data == null) { using (var cstream = new GZipStream(stream, CompressionMode.Compress)) Cached.Save(cstream); } else { stream.Write(data, 0, data.Length); } return(true); }
public void UnregisterObjects(IffFile file) { var objRegistry = Content.Get().WorldObjects; var defs = file.List <OBJD>(); if (defs != null) { foreach (var def in defs) { objRegistry.RemoveObject(def.GUID); } } }
public void RegisterObjects(IffFile file) { var objRegistry = Content.Get().WorldObjects; var defs = file.List <OBJD>(); if (defs != null) { foreach (var def in defs) { objRegistry.AddObject(file, def); } } }
private void CreateTableFile(string path) { InfoTable infotable = new InfoTable(); infotable.Items = new List <TableItem>(); //Far = new FAR1Archive(path, 0); DirectoryInfo dir = new DirectoryInfo(path); foreach (FileInfo file in dir.GetFiles()) { if (file.Extension == ".iff") { var iff = new IffFile(path + "/" + file.Name); ulong FileID = 0; foreach (OBJD obj in iff.List <OBJD>()) { if (obj.IsMultiTile && obj.SubIndex == -1) { FileID = obj.GUID; string name = Path.GetFileNameWithoutExtension(file.Name); infotable.Items.Add(new TableItem() { GUID = FileID.ToString("X"), Name = name, }); listBox1.Items.Add(file.Name + " " + FileID); InfoTable.Save("table.xml", infotable); } else if (!obj.IsMultiTile) { FileID = obj.GUID; string name = Path.GetFileNameWithoutExtension(file.Name); infotable.Items.Add(new TableItem() { GUID = FileID.ToString("X"), Name = name, }); listBox1.Items.Add(file.Name + " " + FileID); InfoTable.Save("table.xml", infotable); } } } } }
/// <summary> /// Reads a SPR chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a SPR chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version1 = io.ReadUInt16(); var version2 = io.ReadUInt16(); uint version = 0; if (version1 == 0) { io.ByteOrder = ByteOrder.BIG_ENDIAN; version = (uint)(((version2|0xFF00)>>8) | ((version2&0xFF)<<8)); } else { version = version1; } ByteOrd = io.ByteOrder; var spriteCount = io.ReadUInt32(); PaletteID = (ushort)io.ReadUInt32(); Frames = new List<SPRFrame>(); if (version != 1001) { var offsetTable = new List<uint>(); for (var i = 0; i < spriteCount; i++) { offsetTable.Add(io.ReadUInt32()); } Offsets = offsetTable; for (var i = 0; i < spriteCount; i++) { var frame = new SPRFrame(this); io.Seek(SeekOrigin.Begin, offsetTable[i]); var guessedSize = ((i + 1 < offsetTable.Count) ? offsetTable[i + 1] : (uint)stream.Length) - offsetTable[i]; frame.Read(version, io, guessedSize); Frames.Add(frame); } } else { while (io.HasMore) { var frame = new SPRFrame(this); frame.Read(version, io, 0); Frames.Add(frame); } } } }
/// <summary> /// Reads a SPR chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a SPR chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version1 = io.ReadUInt16(); var version2 = io.ReadUInt16(); uint version = 0; if (version1 == 0) { io.ByteOrder = ByteOrder.BIG_ENDIAN; version = (uint)(((version2 | 0xFF00) >> 8) | ((version2 & 0xFF) << 8)); } else { version = version1; } ByteOrd = io.ByteOrder; var spriteCount = io.ReadUInt32(); PaletteID = (ushort)io.ReadUInt32(); Frames = new List <SPRFrame>(); if (version != 1001) { var offsetTable = new List <uint>(); for (var i = 0; i < spriteCount; i++) { offsetTable.Add(io.ReadUInt32()); } Offsets = offsetTable; for (var i = 0; i < spriteCount; i++) { var frame = new SPRFrame(this); io.Seek(SeekOrigin.Begin, offsetTable[i]); var guessedSize = ((i + 1 < offsetTable.Count) ? offsetTable[i + 1] : (uint)stream.Length) - offsetTable[i]; frame.Read(version, io, guessedSize); Frames.Add(frame); } } else { while (io.HasMore) { var frame = new SPRFrame(this); frame.Read(version, io, 0); Frames.Add(frame); } } } }
/// <summary> /// Gets a resource. /// </summary> /// <param name="filename">The filename of the resource to get.</param> /// <returns>A GameGlobal instance containing the resource.</returns> public GameGlobal Get(string filename) { string filepath; IffFile iff = null; filename = filename.ToLowerInvariant(); lock (Cache) { if (Cache.ContainsKey(filename)) { return(Cache[filename]); } filepath = Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".iff"); //if we can't load this let it throw an exception... //probably sanity check this when we add user objects. if (File.Exists(filepath)) { iff = new IffFile(filepath); } if (GlobalIffs != null) { iff = this.GlobalIffs.Get(filename + ".iff"); } OTFFile otf = null; try { otf = new OTFFile(Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".otf")); } catch (IOException) { //if we can't load an otf, it probably doesn't exist. } var resource = new GameGlobalResource(iff, otf); var item = new GameGlobal { Resource = resource }; Cache.Add(filename, item); return(item); } }
/// <summary> /// Reads a BCON chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream instance holding a BCON.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var num = io.ReadByte(); Flags = io.ReadByte(); Constants = new ushort[num]; for (var i = 0; i < num; i++) { Constants[i] = io.ReadUInt16(); } } }
protected override Func <string, GameObjectResource> GenerateResource(GameObjectReference reference) { return((fname) => { /** Better set this up! **/ IffFile sprites = null, iff = null; OTFFile tuning = null; if (reference.Source == GameObjectSource.Far) { iff = this.Iffs.Get(reference.FileName + ".iff"); iff.InitHash(); iff.RuntimeInfo.Path = reference.FileName; if (WithSprites) { sprites = this.Sprites.Get(reference.FileName + ".spf"); } var rewrite = PIFFRegistry.GetOTFRewrite(reference.FileName + ".otf"); try { tuning = (rewrite != null) ? new OTFFile(rewrite) : this.TuningTables.Get(reference.FileName + ".otf"); } catch (Exception) { //if any issues occur loading an otf, just silently ignore it. } } else { iff = new IffFile(reference.FileName); iff.InitHash(); iff.RuntimeInfo.Path = reference.FileName; iff.RuntimeInfo.State = IffRuntimeState.Standalone; } if (iff.RuntimeInfo.State == IffRuntimeState.PIFFPatch) { //OBJDs may have changed due to patch. Remove all file references ResetFile(iff); } iff.RuntimeInfo.UseCase = IffUseCase.Object; if (sprites != null) { sprites.RuntimeInfo.UseCase = IffUseCase.ObjectSprites; } return new GameObjectResource(iff, sprites, tuning, reference.FileName, ContentManager); }); }
private void button6_Click(object sender, EventArgs e) { string current = listBox3.SelectedItem.ToString(); string userdata = comboBox1.SelectedItem.ToString(); var iff = new IffFile(userdata + "/Houses" + current + ".iff"); var simi = iff.Get <SIMI>(326); // int value = simi.ArchitectureValue(); //int rooms = simi.Rooms(); }
public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.ReadUInt32(); //pad Version = io.ReadUInt32(); string magic = io.ReadCString(4); var items = (Version > 0x3F) ? 0x40 : 0x20; GlobalData = new short[38]; for (int i = 0; i < items; i++) { var dat = io.ReadInt16(); if (i < GlobalData.Length) { GlobalData[i] = dat; } } Unknown1 = io.ReadInt16(); Unknown2 = io.ReadInt32(); Unknown3 = io.ReadInt32(); GUID1 = io.ReadInt32(); GUID2 = io.ReadInt32(); Unknown4 = io.ReadInt32(); LotValue = io.ReadInt32(); ObjectsValue = io.ReadInt32(); ArchitectureValue = io.ReadInt32(); //short Unknown1 (0x7E1E, 0x702B) //int Unknown2 (2 on house 1, 1 on house 66) //int Unknown3 (0) //int GUID1 //int GUID2 (changes on bulldoze) //int Unknown4 (0) //int LotValue //int ObjectsValue //int ArchitectureValue //the sims tracked a sim's budget over the past few days of gameplay. //this drove the budget window, which never actually came of much use to anyone ever. BudgetDays = new SIMIBudgetDay[6]; for (int i = 0; i < 6; i++) { BudgetDays[i] = new SIMIBudgetDay(io); } } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteByte((byte)Constants.Length); io.WriteByte(Flags); foreach (var c in Constants) { io.WriteUInt16(c); } return(true); } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt16(20004); io.WriteUInt32((uint)Images.Length); foreach (var img in Images) { img.Write(io); } } return(true); }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteInt32(0); io.WriteInt32(1); io.WriteCString("EERT", 4); io.WriteInt32(Entries.Count); foreach (var entry in Entries) { entry.Write(io); } } return(true); }
/// <summary> /// Writes a NBRS chunk to a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A destination stream.</param> public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt32(0); io.WriteUInt32(0x49); io.WriteCString("SRBN", 4); io.WriteInt32(Entries.Count); foreach (var n in NeighbourByID.Values) { n.Save(io); } } return(true); }
/// <summary> /// Reads a BHAV from a stream. /// </summary> /// <param name="iff">Iff instance.</param> /// <param name="stream">A Stream instance holding a BHAV chunk.</param> public override void Read(IffFile iff, System.IO.Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version = io.ReadUInt16(); uint count = 0; if (version == 0x8000) { count = io.ReadUInt16(); io.Skip(8); } else if (version == 0x8001) { count = io.ReadUInt16(); var unknown = io.ReadBytes(8); } else if (version == 0x8002) { count = io.ReadUInt16(); this.Type = io.ReadByte(); this.Args = io.ReadByte(); this.Locals = io.ReadUInt16(); this.Flags = io.ReadUInt16(); io.Skip(2); } else if (version == 0x8003) { this.Type = io.ReadByte(); this.Args = io.ReadByte(); this.Locals = io.ReadByte(); io.Skip(2); this.Flags = io.ReadUInt16(); count = io.ReadUInt32(); } Instructions = new BHAVInstruction[count]; for (var i = 0; i < count; i++) { var instruction = new BHAVInstruction(); instruction.Opcode = io.ReadUInt16(); instruction.TruePointer = io.ReadByte(); instruction.FalsePointer = io.ReadByte(); instruction.Operand = io.ReadBytes(8); Instructions[i] = instruction; } } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt32(0); io.WriteUInt32(Version); io.WriteCString("fJBO", 4); io.WriteInt32(functions.Length); foreach(var func in functions) { io.WriteUInt16(func.ConditionFunction); io.WriteUInt16(func.ActionFunction); } return true; } }
public void SelectPIFF(int index) { if (index == -1) { ActivePIFF = null; } else { ActivePIFF = ActivePIFFs[index]; } ActiveIff = (index == 1 ? (ActiveObj as GameObjectResource)?.Sprites : ActiveObj.MainIff) ?? ActiveObj.MainIff; Render(); EntryList.SelectedItem = null; }
private void TrySaveIff(IffFile file) { var dialog = new SaveFileDialog(); dialog.FileName = file.Filename; dialog.Title = "Saving full IFF " + file.Filename + "..."; FolderSave(dialog); Stream str; if ((str = dialog.OpenFile()) != null) { file.Write(str); str.Close(); } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt32(142); foreach (var prop in VERSION_142_Fields) { io.WriteUInt16((ushort)GetPropertyByName <int>(prop)); } for (int i = VERSION_142_Fields.Length; i < 105; i++) { io.WriteUInt16(0); } } return(true); }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt32(0); io.WriteUInt32((uint)Colors.Length); io.WriteBytes(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); foreach (var col in Colors) { io.WriteByte(col.R); io.WriteByte(col.G); io.WriteByte(col.B); } return(true); } }
/// <summary> /// Reads a OBJf chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a OBJf chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.ReadUInt32(); //pad Version = io.ReadUInt32(); string magic = io.ReadCString(4); functions = new OBJfFunctionEntry[io.ReadUInt32()]; for (int i=0; i<functions.Length; i++) { var result = new OBJfFunctionEntry(); result.ConditionFunction = io.ReadUInt16(); result.ActionFunction = io.ReadUInt16(); functions[i] = result; } } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt32(0); io.WriteUInt32(Version); io.WriteCString("fJBO", 4); io.WriteInt32(functions.Length); foreach (var func in functions) { io.WriteUInt16(func.ConditionFunction); io.WriteUInt16(func.ActionFunction); } return(true); } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteInt32(0); io.WriteInt32(2); //we write out version 2 io.WriteInt32(0); //todo: NCRT ascii io.WriteInt32(Entries.Length); foreach (var entry in Entries) { entry.Write(io); } return(true); } }
/// <summary> /// Reads a DGRP from a stream instance. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream instance holding a DGRP chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version = io.ReadUInt16(); uint imageCount = version < 20003 ? io.ReadUInt16() : io.ReadUInt32(); Images = new DGRPImage[imageCount]; for (var i = 0; i < imageCount; i++) { var image = new DGRPImage(this); image.Read(version, io); Images[i] = image; } } }
/// <summary> /// Reads a SPR chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a SPR chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version1 = io.ReadUInt16(); var version2 = io.ReadUInt16(); uint version = 0; if (version1 == 0) { io.ByteOrder = ByteOrder.BIG_ENDIAN; version = version2; } else { version = version1; } var spriteCount = io.ReadUInt32(); PaletteID = (ushort)io.ReadUInt32(); Frames = new List<SPRFrame>(); if (version != 1001) { var offsetTable = new List<uint>(); for (var i = 0; i < spriteCount; i++) { offsetTable.Add(io.ReadUInt32()); } for (var i = 0; i < spriteCount; i++) { var frame = new SPRFrame(this); frame.Read(version, io); Frames.Add(frame); } } else { while (io.HasMore) { var frame = new SPRFrame(this); frame.Read(version, io); Frames.Add(frame); } } } }
public void Save() { //save the house first var iff = new IffFile(); vm.TS1State.UpdateSIMI(vm); var marshal = vm.Save(); var fsov = new FSOV(); fsov.ChunkLabel = "Simitone Lot Data"; fsov.ChunkID = 1; fsov.ChunkProcessed = true; fsov.ChunkType = "FSOV"; fsov.AddedByPatch = true; using (var stream = new MemoryStream()) { marshal.SerializeInto(new BinaryWriter(stream)); fsov.Data = stream.ToArray(); } iff.AddChunk(fsov); var simi = vm.TS1State.SimulationInfo; simi.ChunkProcessed = true; simi.AddedByPatch = true; iff.AddChunk(simi); Texture2D roofless = null; var thumb = World.GetLotThumb(GameFacade.GraphicsDevice, (tex) => roofless = FSO.Common.Utils.TextureUtils.Decimate(tex, GameFacade.GraphicsDevice, 2, false)); thumb = FSO.Common.Utils.TextureUtils.Decimate(thumb, GameFacade.GraphicsDevice, 2, false); var tPNG = GeneratePNG(thumb); tPNG.ChunkID = 513; iff.AddChunk(tPNG); var rPNG = GeneratePNG(roofless); rPNG.ChunkID = 512; iff.AddChunk(rPNG); Content.Get().Neighborhood.SaveHouse(vm.GetGlobalValue(10), iff); Content.Get().Neighborhood.SaveNeighbourhood(true); }
/// <summary> /// Reads a SPR chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a SPR chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version1 = io.ReadUInt16(); var version2 = io.ReadUInt16(); uint version = 0; if (version1 == 0) { io.ByteOrder = ByteOrder.BIG_ENDIAN; version = version2; } else { version = version1; } var spriteCount = io.ReadUInt32(); PaletteID = (ushort)io.ReadUInt32(); Frames = new List <SPRFrame>(); if (version != 1001) { var offsetTable = new List <uint>(); for (var i = 0; i < spriteCount; i++) { offsetTable.Add(io.ReadUInt32()); } for (var i = 0; i < spriteCount; i++) { var frame = new SPRFrame(this); frame.Read(version, io); Frames.Add(frame); } } else { while (io.HasMore) { var frame = new SPRFrame(this); frame.Read(version, io); Frames.Add(frame); } } } }
public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline) { if (Sprites == null) { Sprites = new Files.Formats.IFF.IffFile(Content.Content.Get().GetPath("objectdata/globals/sprites.iff")); WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice); } if (Headline.Operand.Group != VMSetBalloonHeadlineOperandGroup.Algorithmic) Sprite = Sprites.Get<SPR>((ushort)(GroupOffsets[(int)Headline.Operand.Group] + Headline.Index)); if (Headline.Operand.Type != 255 && Headline.Operand.Type != 3) BGSprite = Sprites.Get<SPR>((ushort)(GroupOffsets[(int)VMSetBalloonHeadlineOperandGroup.Balloon] + Headline.Operand.Type)); LastZoom = WorldZoom.Near; RecalculateTarget(); }
/// <summary> /// Reads a PALT chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a PALT chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version = io.ReadUInt32(); var numEntries = io.ReadUInt32(); var reserved = io.ReadBytes(8); Colors = new Color[numEntries]; for (var i = 0; i < numEntries; i++) { var r = io.ReadByte(); var g = io.ReadByte(); var b = io.ReadByte(); Colors[i] = new Color(r, g, b); } } }
/// <summary> /// Reads a SPR2 chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a SPR2 chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version = io.ReadUInt32(); uint spriteCount = 0; if (version == 1000) { spriteCount = io.ReadUInt32(); DefaultPaletteID = io.ReadUInt32(); var offsetTable = new uint[spriteCount]; for (var i = 0; i < spriteCount; i++) { offsetTable[i] = io.ReadUInt32(); } Frames = new SPR2Frame[spriteCount]; for (var i = 0; i < spriteCount; i++) { var frame = new SPR2Frame(this); io.Seek(SeekOrigin.Begin, offsetTable[i]); var guessedSize = ((i + 1 < offsetTable.Length) ? offsetTable[i + 1] : (uint)stream.Length) - offsetTable[i]; frame.Read(version, io, guessedSize); Frames[i] = frame; } } else if (version == 1001) { DefaultPaletteID = io.ReadUInt32(); spriteCount = io.ReadUInt32(); Frames = new SPR2Frame[spriteCount]; for (var i = 0; i < spriteCount; i++) { var frame = new SPR2Frame(this); frame.Read(version, io, 0); Frames[i] = frame; } } } }
public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { Version = io.ReadUInt16(); SourceIff = io.ReadVariableLengthPascalString(); Entries = new PIFFEntry[io.ReadUInt16()]; for (int i=0; i<Entries.Length; i++) { var e = new PIFFEntry(); e.Type = io.ReadCString(4); e.ChunkID = io.ReadUInt16(); e.Delete = io.ReadByte()>0; if (!e.Delete) { e.ChunkLabel = io.ReadVariableLengthPascalString(); e.ChunkFlags = io.ReadUInt16(); if (Version > 0) e.NewChunkID = io.ReadUInt16(); else e.NewChunkID = e.ChunkID; e.NewDataSize = io.ReadUInt32(); var size = io.ReadUInt32(); e.Patches = new PIFFPatch[size]; uint lastOff = 0; for (int j=0; j<e.Patches.Length; j++) { var p = new PIFFPatch(); p.Offset = lastOff + io.ReadVarLen(); lastOff = p.Offset; p.Size = io.ReadVarLen(); p.Mode = (PIFFPatchMode)io.ReadByte(); if (p.Mode == PIFFPatchMode.Add) p.Data = io.ReadBytes(p.Size); e.Patches[j] = p; } } Entries[i] = e; } } }
/// <summary> /// Reads a GLOB chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a GLOB chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { StringBuilder temp = new StringBuilder(); var num = io.ReadByte(); if (num < 48) { //less than smallest ASCII value for valid filename character, so assume this is a pascal string temp.Append(io.ReadCString(num)); } else { //we're actually a null terminated string! temp.Append((char)num); while (stream.Position < stream.Length) { char read = (char)io.ReadByte(); if (read == 0) break; else temp.Append(read); } } Name = temp.ToString(); } }
public static void Init(string basePath) { PIFFsByName = new Dictionary<string, List<IffFile>>(); IsPIFFUser = new Dictionary<string, bool>(); //Directory.CreateDirectory(basePath); string[] paths = Directory.GetFiles(basePath, "*.piff", SearchOption.AllDirectories); for (int i = 0; i < paths.Length; i++) { string entry = paths[i].Replace('\\', '/'); bool user = entry.Contains("User/"); string filename = Path.GetFileName(entry); IffFile piffFile = new IffFile(entry); PIFF piff = piffFile.List<PIFF>()[0]; if (IsPIFFUser.ContainsKey(piff.SourceIff)) { var old = IsPIFFUser[piff.SourceIff]; if (old != user) { if (user) { //remove old piffs, as they have been overwritten by this user piff. PIFFsByName[piff.SourceIff].Clear(); IsPIFFUser[piff.SourceIff] = true; } else continue; //a user piff exists. ignore these ones. } } else IsPIFFUser.Add(piff.SourceIff, user); if (!PIFFsByName.ContainsKey(piff.SourceIff)) PIFFsByName.Add(piff.SourceIff, new List<IffFile>()); PIFFsByName[piff.SourceIff].Add(piffFile); } }
/// <summary> /// Reads a TPRP from a stream. /// </summary> /// <param name="iff">Iff instance.</param> /// <param name="stream">A Stream instance holding a TPRP chunk.</param> public override void Read(IffFile iff, System.IO.Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var zero = io.ReadInt32(); var version = io.ReadInt32(); var name = io.ReadCString(4); //"PRPT", or randomly 4 null characters for no good reason var pCount = io.ReadInt32(); var lCount = io.ReadInt32(); ParamNames = new string[pCount]; LocalNames = new string[lCount]; for (int i = 0; i < pCount; i++) { ParamNames[i] = (version == 5) ? io.ReadPascalString() : io.ReadNullTerminatedString(); } for (int i = 0; i < lCount; i++) { LocalNames[i] = (version == 5) ? io.ReadPascalString() : io.ReadNullTerminatedString(); } //TODO: flags and unknowns } }
/// <summary> /// Reads a TTAB chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a TTAB chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { InteractionByIndex.Clear(); Interactions = new TTABInteraction[io.ReadUInt16()]; if (Interactions.Length == 0) return; //no interactions, don't bother reading remainder. var version = io.ReadUInt16(); IOProxy iop; if (version != 9 && version != 10) iop = new TTABNormal(io); else { var compressionCode = io.ReadByte(); if (compressionCode != 1) throw new Exception("hey what!!"); iop = new TTABFieldEncode(io); //haven't guaranteed that this works, since none of the objects in the test lot use it. } for (int i = 0; i < Interactions.Length; i++) { var result = new TTABInteraction(); result.ActionFunction = iop.ReadUInt16(); result.TestFunction = iop.ReadUInt16(); result.MotiveEntries = new TTABMotiveEntry[iop.ReadUInt32()]; result.Flags = (TTABFlags)iop.ReadUInt32(); result.TTAIndex = iop.ReadUInt32(); if (version > 6) result.AttenuationCode = iop.ReadUInt32(); result.AttenuationValue = iop.ReadFloat(); result.AutonomyThreshold = iop.ReadUInt32(); result.JoiningIndex = iop.ReadInt32(); for (int j = 0; j < result.MotiveEntries.Length; j++) { var motive = new TTABMotiveEntry(); if (version > 6) motive.EffectRangeMinimum = iop.ReadInt16(); motive.EffectRangeMaximum = iop.ReadInt16(); if (version > 6) motive.PersonalityModifier = iop.ReadUInt16(); result.MotiveEntries[j] = motive; } if (version > 9) { result.Flags2 = (TSOFlags)iop.ReadUInt32(); } Interactions[i] = result; InteractionByIndex.Add(result.TTAIndex, result); } } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt16(20004); io.WriteUInt32((uint)Images.Length); foreach (var img in Images) { img.Write(io); } } return true; }
public void RegisterObjects(IffFile file) { var objRegistry = Content.Get().WorldObjects; var defs = file.List<OBJD>(); if (defs != null) { foreach (var def in defs) { objRegistry.AddObject(file, def); } } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt16((ushort)Interactions.Length); io.WriteUInt16(8); //version. don't save to high version cause we can't write out using the complex io proxy. for (int i = 0; i < Interactions.Length; i++) { var action = Interactions[i]; io.WriteUInt16(action.ActionFunction); io.WriteUInt16(action.TestFunction); io.WriteUInt32((uint)action.MotiveEntries.Length); io.WriteUInt32((uint)action.Flags); io.WriteUInt32(action.TTAIndex); io.WriteUInt32(action.AttenuationCode); io.WriteFloat(action.AttenuationValue); io.WriteUInt32(action.AutonomyThreshold); io.WriteInt32(action.JoiningIndex); for (int j=0; j < action.MotiveEntries.Length; j++) { var mot = action.MotiveEntries[j]; io.WriteInt16(mot.EffectRangeMinimum); io.WriteInt16(mot.EffectRangeMaximum); io.WriteUInt16(mot.PersonalityModifier); } //TODO: write out TSOFlags } } return true; }
/// <summary> /// Reads a STR chunk from a stream. /// </summary> /// <param name="iff">An Iff instance.</param> /// <param name="stream">A Stream object holding a STR chunk.</param> public override void Read(IffFile iff, Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var formatCode = io.ReadInt16(); LanguageSets = new STRLanguageSet[20]; if (!io.HasMore){ for (int i = 0; i < 20; i++) LanguageSets[i] = new STRLanguageSet { Strings = new STRItem[0] }; return; } if (formatCode == 0) { var numStrings = io.ReadUInt16(); for (int i = 0; i < 20; i++) LanguageSets[i] = new STRLanguageSet { Strings = new STRItem[0] }; LanguageSets[0].Strings = new STRItem[numStrings]; for (var i = 0; i < numStrings; i++) { LanguageSets[0].Strings[i] = new STRItem { Value = io.ReadPascalString() }; } } //This format changed 00 00 to use C strings rather than Pascal strings. else if (formatCode == -1) { var numStrings = io.ReadUInt16(); for (int i = 0; i < 20; i++) LanguageSets[i] = new STRLanguageSet { Strings = new STRItem[0] }; LanguageSets[0].Strings = new STRItem[numStrings]; for (var i = 0; i < numStrings; i++) { LanguageSets[0].Strings[i] = new STRItem { Value = io.ReadNullTerminatedUTF8() }; } } //This format changed FF FF to use string pairs rather than single strings. else if (formatCode == -2) { var numStrings = io.ReadUInt16(); for (int i = 0; i < 20; i++) LanguageSets[i] = new STRLanguageSet { Strings = new STRItem[0] }; LanguageSets[0].Strings = new STRItem[numStrings]; for (var i = 0; i < numStrings; i++) { LanguageSets[0].Strings[i] = new STRItem { Value = io.ReadNullTerminatedString(), Comment = io.ReadNullTerminatedString() }; } } //This format changed FD FF to use a language code. else if (formatCode == -3) { var numStrings = io.ReadUInt16(); for (int i = 0; i < 20; i++) LanguageSets[i] = new STRLanguageSet { Strings = new STRItem[0] }; List<STRItem>[] LangSort = new List<STRItem>[20]; for (var i = 0; i < numStrings; i++) { var item = new STRItem { LanguageCode = io.ReadByte(), Value = io.ReadNullTerminatedString(), Comment = io.ReadNullTerminatedString() }; var lang = item.LanguageCode; if (lang == 0) lang = 1; else if (lang < 0 || lang > 20) continue; //??? if (LangSort[lang - 1] == null) { LangSort[lang-1] = new List<STRItem>(); } LangSort[lang - 1].Add(item); } for (int i=0; i<LanguageSets.Length; i++) { if (LangSort[i] != null) LanguageSets[i].Strings = LangSort[i].ToArray(); } } //This format is only used in The Sims Online. The format is essentially a performance improvement: //it counteracts both the short string limit of 255 characters found in 00 00 and the inherent slowness //of null-terminated strings in the other formats (which requires two passes over each string), and it //also provides a string pair count for each language set which eliminates the need for two passes over //each language set. else if (formatCode == -4) { var numLanguageSets = io.ReadByte(); this.LanguageSets = new STRLanguageSet[numLanguageSets]; for(var i=0; i < numLanguageSets; i++) { var item = new STRLanguageSet(); var numStringPairs = io.ReadUInt16(); item.Strings = new STRItem[numStringPairs]; for (var x = 0; x < numStringPairs; x++) { item.Strings[x] = new STRItem { LanguageCode = (byte)(io.ReadByte() + 1), Value = io.ReadVariableLengthPascalString(), Comment = io.ReadVariableLengthPascalString() }; } this.LanguageSets[i] = item; } } } }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteInt16(-4); io.WriteByte(20); foreach (var set in LanguageSets) { io.WriteUInt16((ushort)set.Strings.Length); foreach (var str in set.Strings) { io.WriteByte((byte)(str.LanguageCode - 1)); io.WriteVariableLengthPascalString(str.Value); io.WriteVariableLengthPascalString(str.Comment); } } return true; } }
public void SaveChange(IffFile file) { lock (this) { if (file.RuntimeInfo.State == IffRuntimeState.Standalone) { //just save out iff var filename = file.RuntimeInfo.Path; Directory.CreateDirectory(Path.GetDirectoryName(filename)); using (var stream = new FileStream(filename, FileMode.Create)) file.Write(stream); foreach (var chunk in file.ListAll()) { chunk.RuntimeInfo = ChunkRuntimeState.Normal; } } else { string dest = Path.Combine(FSOEnvironment.ContentDir, ((file.RuntimeInfo.State == IffRuntimeState.PIFFClone) ? "Objects/" : "Patch/User/")); Directory.CreateDirectory(dest); if (file.RuntimeInfo.State == IffRuntimeState.ReadOnly) { file.RuntimeInfo.State = IffRuntimeState.PIFFPatch; } var stringResources = new HashSet<Type> { typeof(STR), typeof(CTSS), typeof(TTAs) }; var sprites = (file.RuntimeInfo.UseCase == IffUseCase.ObjectSprites); file.RuntimeInfo.Patches.Clear(); var piff = FSO.Files.Formats.PiffEncoder.GeneratePiff(file, null, stringResources); string name = file.Filename.Substring(0, file.Filename.Length - 4); //get without extension if (piff != null) { var filename = dest + name + (sprites ? ".spf" : "") + ".piff"; using (var stream = new FileStream(filename, FileMode.Create)) piff.Write(stream); file.RuntimeInfo.Patches.Add(piff); } if (!sprites) { piff = FSO.Files.Formats.PiffEncoder.GeneratePiff(file, stringResources, null); if (piff != null) { var filename = dest + name + ".str.piff"; using (var stream = new FileStream(filename, FileMode.Create)) piff.Write(stream); file.RuntimeInfo.Patches.Add(piff); } } } file.RuntimeInfo.Dirty = false; ChangedFiles.Remove(file); } }
public void UnregisterObjects(IffFile file) { var objRegistry = Content.Get().WorldObjects; var defs = file.List<OBJD>(); if (defs != null) { foreach (var def in defs) { objRegistry.RemoveObject(def.GUID); } } }
public override void Read(IffFile iff, System.IO.Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)){ var zero = io.ReadUInt32(); var version = io.ReadUInt32(); var slotMagic = io.ReadBytes(4); var numSlots = io.ReadUInt32(); Slots = new Dictionary<ushort, List<SLOTItem>>(); /** The span for version 4 is 34. * The span for version 6 is 54. * The span for version 7 is 58. * The span for version 8 is 62. * The span for version 9 is 66. * The span for version 10 is 70. **/ for (var i = 0; i < numSlots; i++){ io.Mark(); var item = new SLOTItem(); item.Type = io.ReadUInt16(); item.Offset = new Vector3( io.ReadFloat(), io.ReadFloat(), io.ReadFloat() ); var standing = io.ReadInt32(); var sitting = io.ReadInt32(); var ground = io.ReadInt32(); var rsflags = io.ReadInt32(); var snaptargetslot = io.ReadInt32(); var minproximity = io.ReadInt32(); //bonuses (0 means never) item.Standing = standing; //score bonus for standing destinations item.Sitting = sitting; //score bonus for sitting destinations item.Ground = ground; //score bonus for sitting on ground item.Rsflags = (SLOTFlags)rsflags; item.SnapTargetSlot = snaptargetslot; item.MinProximity = minproximity; if (version >= 6) { var maxproximity = io.ReadInt32(); var optimalproximity = io.ReadInt32(); var i9 = io.ReadInt32(); var i10 = io.ReadInt32(); item.MaxProximity = maxproximity; item.OptimalProximity = optimalproximity; } if (version <= 9) { item.MinProximity *= 16; item.MaxProximity *= 16; item.OptimalProximity *= 16; } if (version >= 7) item.Gradient = io.ReadFloat(); if (version >= 8) item.Height = io.ReadInt32(); //the below cases are just here for breakpoint purposes //TODO: find use cases? if (item.Height == 9) item.Height = 9; if (item.Height == 0) item.Height = 5; //use offset height, nonstandard. if (version >= 9) item.Facing = (SLOTFacing)io.ReadInt32(); if (version >= 10) item.Resolution = io.ReadInt32(); if (!Slots.ContainsKey(item.Type)) Slots.Add(item.Type, new List<SLOTItem>()); Slots[item.Type].Add(item); } } }
public void IffChanged(IffFile file) { file.RuntimeInfo.Dirty = true; lock (this) ChangedFiles.Add(file); }
public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { io.WriteUInt32(1001); io.WriteUInt32(DefaultPaletteID); if (Frames == null) io.WriteUInt32(0); else { io.WriteUInt32((uint)Frames.Length); foreach (var frame in Frames) { frame.Write(io); } } return true; } }