예제 #1
0
        public Story Read(Stream stream)
        {
            var story = new Story();

            using (var reader = new OsiReader(stream, story))
            {
                var header = new SaveFileHeader();
                header.Read(reader);
                reader.MinorVersion = header.MinorVersion;
                reader.MajorVersion = header.MajorVersion;
                story.MinorVersion  = header.MinorVersion;
                story.MajorVersion  = header.MajorVersion;

                if (reader.Ver > OsiVersion.VerLastSupported)
                {
                    var msg = String.Format(
                        "Osiris version v{0}.{1} unsupported; this tool supports loading up to version 1.12.",
                        reader.MajorVersion, reader.MinorVersion
                        );
                    throw new InvalidDataException(msg);
                }

                if (reader.Ver >= OsiVersion.VerScramble)
                {
                    reader.Scramble = 0xAD;
                }

                if (reader.Ver >= OsiVersion.VerAddTypeMap)
                {
                    story.Types = ReadTypes(reader);
                    foreach (var type in story.Types)
                    {
                        if (type.Value.Alias != 0)
                        {
                            reader.TypeAliases.Add(type.Key, type.Value.Alias);
                        }
                    }
                }
                else
                {
                    story.Types = new Dictionary <uint, OsirisType>();
                }

                if (reader.Ver >= OsiVersion.VerExternalStringTable && reader.Ver < OsiVersion.VerRemoveExternalStringTable)
                {
                    story.ExternalStringTable = ReadStrings(reader);
                }
                else
                {
                    story.ExternalStringTable = new List <string>();
                }

                story.Types[0] = OsirisType.MakeBuiltin(0, "UNKNOWN");
                story.Types[1] = OsirisType.MakeBuiltin(1, "INTEGER");

                if (reader.Ver >= OsiVersion.VerEnhancedTypes)
                {
                    story.Types[2] = OsirisType.MakeBuiltin(2, "INTEGER64");
                    story.Types[3] = OsirisType.MakeBuiltin(3, "REAL");
                    story.Types[4] = OsirisType.MakeBuiltin(4, "STRING");
                    story.Types[5] = OsirisType.MakeBuiltin(5, "GUIDSTRING");
                }
                else
                {
                    story.Types[2] = OsirisType.MakeBuiltin(2, "FLOAT");
                    story.Types[3] = OsirisType.MakeBuiltin(3, "STRING");
                }

                story.DivObjects    = reader.ReadList <OsirisDivObject>();
                story.Functions     = reader.ReadList <Function>();
                story.Nodes         = ReadNodes(reader);
                story.Adapters      = ReadAdapters(reader);
                story.Databases     = ReadDatabases(reader);
                story.Goals         = ReadGoals(reader, story);
                story.GlobalActions = reader.ReadList <Call>();

                foreach (var node in story.Nodes)
                {
                    node.Value.PostLoad(story);
                }

                return(story);
            }
        }
예제 #2
0
        public void Write(Stream stream, Story story)
        {
            using (Writer = new OsiWriter(stream))
            {
                foreach (var node in story.Nodes)
                {
                    node.Value.PreSave(story);
                }

                Writer.MajorVersion = story.MajorVersion;
                Writer.MinorVersion = story.MinorVersion;

                var header = new SaveFileHeader();
                if (Writer.Ver >= OsiVersion.VerExternalStringTable)
                {
                    header.Version = "Osiris save file dd. 03/30/17 07:28:20. Version 1.8.";
                }
                else
                {
                    header.Version = "Osiris save file dd. 02/10/15 12:44:13. Version 1.5.";
                }
                header.MajorVersion = story.MajorVersion;
                header.MinorVersion = story.MinorVersion;
                header.BigEndian    = false;
                header.Unused       = 0;
                // Debug flags used in D:OS EE and D:OS 2
                header.DebugFlags = 0x000C10A0;
                header.Write(Writer);

                if (Writer.Ver > OsiVersion.VerLastSupported)
                {
                    var msg = String.Format(
                        "Osiris version v{0}.{1} unsupported; this tool supports saving up to version 1.11.",
                        Writer.MajorVersion, Writer.MinorVersion
                        );
                    throw new InvalidDataException(msg);
                }

                if (Writer.Ver >= OsiVersion.VerScramble)
                {
                    Writer.Scramble = 0xAD;
                }

                if (Writer.Ver >= OsiVersion.VerAddTypeMap)
                {
                    // Don't export builtin types, only externally declared ones
                    var types = story.Types.Values.Where(t => !t.IsBuiltin).ToList();
                    WriteTypes(types);
                }

                // TODO: regenerate string table?
                if (Writer.Ver >= OsiVersion.VerExternalStringTable && Writer.Ver < OsiVersion.VerRemoveExternalStringTable)
                {
                    WriteStrings(story.ExternalStringTable);
                }

                Writer.WriteList(story.DivObjects);
                Writer.WriteList(story.Functions);
                WriteNodes(story.Nodes);
                WriteAdapters(story.Adapters);
                WriteDatabases(story.Databases);
                WriteGoals(story.Goals);
                Writer.WriteList(story.GlobalActions);

                foreach (var node in story.Nodes)
                {
                    node.Value.PostSave(story);
                }
            }
        }
예제 #3
0
        public Story Read(Stream stream)
        {
            var story = new Story();

            using (var reader = new OsiReader(stream, story))
            {
                var header = new SaveFileHeader();
                header.Read(reader);
                reader.MinorVersion = header.MinorVersion;
                reader.MajorVersion = header.MajorVersion;
                story.MinorVersion  = header.MinorVersion;
                story.MajorVersion  = header.MajorVersion;

                if (reader.Ver > OsiVersion.VerLastSupported)
                {
                    var msg = String.Format(
                        "Osiris version v{0}.{1} unsupported; this tool supports loading up to version 1.12.",
                        reader.MajorVersion, reader.MinorVersion
                        );
                    throw new InvalidDataException(msg);
                }

                if (reader.Ver >= OsiVersion.VerScramble)
                {
                    reader.Scramble = 0xAD;
                }

                story.Types = ReadTypes(reader, story);

                if (reader.Ver >= OsiVersion.VerExternalStringTable && reader.Ver < OsiVersion.VerRemoveExternalStringTable)
                {
                    story.ExternalStringTable = ReadStrings(reader);
                }
                else
                {
                    story.ExternalStringTable = new List <string>();
                }

                story.Types[0] = OsirisType.MakeBuiltin(0, "UNKNOWN");
                story.Types[1] = OsirisType.MakeBuiltin(1, "INTEGER");

                if (reader.Ver >= OsiVersion.VerEnhancedTypes)
                {
                    story.Types[2] = OsirisType.MakeBuiltin(2, "INTEGER64");
                    story.Types[3] = OsirisType.MakeBuiltin(3, "REAL");
                    story.Types[4] = OsirisType.MakeBuiltin(4, "STRING");
                    // BG3 defines GUIDSTRING in the .osi file
                    if (!story.Types.ContainsKey(5))
                    {
                        story.Types[5] = OsirisType.MakeBuiltin(5, "GUIDSTRING");
                    }
                }
                else
                {
                    story.Types[2] = OsirisType.MakeBuiltin(2, "FLOAT");
                    story.Types[3] = OsirisType.MakeBuiltin(3, "STRING");

                    // Populate custom type IDs for versions that had no type alias map
                    if (reader.Ver < OsiVersion.VerAddTypeMap)
                    {
                        for (byte typeId = 4; typeId <= 17; typeId++)
                        {
                            story.Types[typeId]       = OsirisType.MakeBuiltin(typeId, $"TYPE{typeId}");
                            story.Types[typeId].Alias = 3;
                            reader.TypeAliases.Add(typeId, 3);
                        }
                    }
                }

                story.DivObjects    = reader.ReadList <OsirisDivObject>();
                story.Functions     = reader.ReadList <Function>();
                story.Nodes         = ReadNodes(reader);
                story.Adapters      = ReadAdapters(reader);
                story.Databases     = ReadDatabases(reader);
                story.Goals         = ReadGoals(reader, story);
                story.GlobalActions = reader.ReadList <Call>();

                story.FunctionSignatureMap = new Dictionary <string, Function>();
                foreach (var func in story.Functions)
                {
                    story.FunctionSignatureMap.Add(func.Name.Name + "/" + func.Name.Parameters.Types.Count.ToString(), func);
                }

                foreach (var node in story.Nodes)
                {
                    node.Value.PostLoad(story);
                }

                return(story);
            }
        }